Repository: monarch-initiative/pyphetools (language: python)

Issue:
Hpotk qc



Discussion / hints:

Fix patch:
diff --git a/.github/workflows/documentation.yaml b/.github/workflows/documentation.yaml
deleted file mode 100644
index 3d44ed92..00000000
--- a/.github/workflows/documentation.yaml
+++ /dev/null
@@ -1,52 +0,0 @@
-name: Sphinx Documentation
-on:
-  # runs with manual start from Actions tab
-  workflow_dispatch:
-  # runs on pushes
-  push:
-    branches: [  main ]
-
-jobs:
-  build-docs:
-    runs-on: ubuntu-latest
-
-    steps:
-    - name: Checkout
-      uses: actions/checkout@v3
-      with:
-        fetch-depth: 0 # otherwise, you will fail to push refs to dest repo
-        ref: ${{ github.ref }}
-
-    - name: Set up Python 3.
-      uses: actions/setup-python@v4
-      with:
-        python-version: 3.9
-
-    - name: install
-      run:  pip install sphinx sphinx-rtd-theme sphinx-copybutton 
-
-    - name: Build documentation.
-      run: |
-          ## Init the target folder. 
-          # We will put all site documentation there.
-          mkdir -p gh-pages
-          touch gh-pages/.nojekyll
-
-          git checkout main
-          python3 -m pip install .
-          ## Init the target folder.
-          # We will put all site documentation there.
-          mkdir -p gh-pages
-          sphinx-apidoc --separate --module-first -d 4 -H "API reference" --follow-links -o docs/apidocs src/pyphetools
-          cd docs
-          make html
-          mv _build/html/* ../gh-pages
-          
-  
-    - name: Deploy documentation.
-      if: ${{ github.event_name == 'push' }}
-      uses: JamesIves/github-pages-deploy-action@v4.4.1
-      with:
-        branch: gh-pages
-        clean: true
-        folder: gh-pages
diff --git a/.github/workflows/mkdocs-deploy.yml b/.github/workflows/mkdocs-deploy.yml
new file mode 100644
index 00000000..f4d4274f
--- /dev/null
+++ b/.github/workflows/mkdocs-deploy.yml
@@ -0,0 +1,26 @@
+name: mkdocs-generation 
+on:
+  push:
+    branches:
+      - master 
+      - main
+permissions:
+  contents: write
+jobs:
+  deploy:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - uses: actions/setup-python@v4
+        with:
+          python-version: 3.x
+      - uses: actions/cache@v2
+        with:
+          key: ${{ github.ref }}
+          path: .cache
+      - run: pip install mkdocs-material
+      - run: pip install mkdocs-material[imaging]
+      - run: pip install pillow cairosvg
+      - run: pip install mkdocs-material-extensions
+      - run: pip install mkdocstrings[python]
+      - run: mkdocs gh-deploy --force
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 8d76abb6..7698b8f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,8 +69,8 @@ instance/
 .scrapy
 
 # Sphinx documentation
-docs/_build/
-docs/apidocs/
+docsOLD/_build/
+docsOLD/apidocs/
 
 # PyBuilder
 target/
@@ -141,7 +141,7 @@ generated/
 modules.rst
 pyphetools.analyze.rst
 pyphetools.creation.rst
-pyphetools.output.rst
+pyphetools.visualize.rst
 pyphetools.rst
 pyphetools.validation.rst
 test.rst
diff --git a/docs/Makefile b/docs/Makefile
deleted file mode 100644
index e78a80b3..00000000
--- a/docs/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-# Minimal makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS    =
-SPHINXBUILD   = sphinx-build
-SPHINXPROJ    = pyphetools
-SOURCEDIR     = .
-BUILDDIR      = _build
-
-# Put it first so that "make" without argument is like "make help".
-help:
-	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
-
-.PHONY: help Makefile
-
-# Catch-all target: route all unknown targets to Sphinx using the new
-# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
-%: Makefile
-	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
\ No newline at end of file
diff --git a/docs/_static/pyphetools.css b/docs/_static/pyphetools.css
deleted file mode 100644
index faea178e..00000000
--- a/docs/_static/pyphetools.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.wy-nav-content {
-    max-width: 75% !important;
-}
\ No newline at end of file
diff --git a/docs/api.md b/docs/api.md
new file mode 100644
index 00000000..ae404586
--- /dev/null
+++ b/docs/api.md
@@ -0,0 +1,6 @@
+# API Documentation
+
+
+# Creation module
+
+::: pyphetools.creation
\ No newline at end of file
diff --git a/docs/conf.py b/docs/conf.py
deleted file mode 100644
index 50e57a11..00000000
--- a/docs/conf.py
+++ /dev/null
@@ -1,91 +0,0 @@
-import os
-import sys
-
-
-
-# -- Project information -----------------------------------------------------
-# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
-
-# General information about the project.
-project = u'pyphetools'
-copyright = u'2023'
-author = u'Peter Robinson, Daniel Danis'
-release = '0.2.1dev'
-
-
-
-# -- General configuration ---------------------------------------------------
-# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
-
-pyphetools_src = os.path.abspath(os.path.join('..', 'src'))
-sys.path.insert(0, pyphetools_src)
-extensions = [
-    'sphinx.ext.autodoc',
-    'sphinx.ext.autosummary',
-    'sphinx.ext.doctest',
-    'sphinx.ext.napoleon',
-    'sphinx.ext.viewcode',
-    'sphinx.ext.intersphinx',
-    'sphinx_copybutton'
-]
-
-templates_path = ['_templates']
-exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
-
-# -- Autodoc setup ------------------------------------------------------------
-
-autodoc_member_order = 'bysource'
-
-# -- Doctest setup ------------------------------------------------------------
-
-doctest_path = [pyphetools_src]
-doctest_test_doctest_blocks = ""
-
-# Nothing special here
-doctest_global_setup = """
-"""
-
-source_suffix = '.rst'
-
-# The master toctree document.
-master_doc = 'index'
-
-
-# -- Intersphinx setup --------------------------------------------------------
-intersphinx_mapping = {
-    "python": ("https://docs.python.org/3/", None),
-    # TODO - change to stable when we arrive there
-    "hpotk": ("https://thejacksonlaboratory.github.io/hpo-toolkit/latest/", None),
-    "sklearn": ("https://scikit-learn.org/stable/", None),
-    "numpy": ("https://numpy.org/doc/stable/", None),
-    "matplotlib": ("https://matplotlib.org/stable/", None),
-    "seaborn": ("https://seaborn.pydata.org/", None),
-}
-
-# -- Sphinx copybutton setup --------------------------------------------------
-# Exclude `>>>` when copying the cell
-copybutton_exclude = '.linenos, .gp'
-
-# -- Options for HTML output --------------------------------------------------
-# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
-
-# If true, `todo` and `todoList` produce output, else they produce nothing.
-todo_include_todos = True
-pygments_style = 'sphinx'
-html_theme = "sphinx_rtd_theme"
-# html_theme_options = {}
-language = 'en'
-
-
-
-html_static_path = ['_static']
-# html_style = 'css/isopret.css'
-html_css_files = ['pyphetools.css']
-
-
-
-# -- Options for HTMLHelp output ------------------------------------------
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'pyphetools'
-
diff --git a/docs/developers.rst b/docs/developers.md
similarity index 50%
rename from docs/developers.rst
rename to docs/developers.md
index e40a72d6..620c868f 100644
--- a/docs/developers.rst
+++ b/docs/developers.md
@@ -1,38 +1,30 @@
-.. _developers:
+# For developers
 
+## Updating package in PyPI
 
-==============
-For developers
-==============
 
-Updating package in PyPI
-^^^^^^^^^^^^^^^^^^^^^^^^
-We have installed the package in the Python Package Index (pypi) at [pyphentools](https://pypi.org/project/pyphetools/).
+We have installed the package in the Python Package Index (pypi) at [pyphetools](https://pypi.org/project/pyphetools/){:target="\_blank"}.
 To update the version, first make sure the build and twine packages are installed (if necessary).
 
 
-.. code-block:: shell
-   
-   python3 -m pip install --upgrade build
-   python3 -m pip install --upgrade twine
-
+```bash
+python3 -m pip install --upgrade build
+python3 -m pip install --upgrade twine
+```
 
 To update the version in PyPI, update the version number in the pyproject.toml file, and 
 execute the following commands to build and install.
 
-.. code-block:: shell
-
-   python3 -m build
-   python3 -m twine upload dist/*
+```bash title="updating package in PyPI"
+python3 -m build
+python3 -m twine upload dist/*
+```
 
+## Unit testing
 
-Unit testing
-^^^^^^^^^^^^
 
 Unit tests were written for pytest, which can be installed with pip and run from the top-level directory as
 
-
-.. code-block:: shell
-
-   pytest
-
+```bash
+pytest
+```
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 00000000..761c630f
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,15 @@
+# pyphetools
+
+
+pyphetools is a Python package for creating  
+[GA4GH phenopackets](https://phenopacket-schema.readthedocs.io/en/latest/){:target="\_blank"}
+from tabular data such as databases or supplemental files found in
+the medical literature.
+
+
+### Feedback
+
+
+The best place to leave feedback, ask questions, and report bugs is the 
+[Pyphetools Issue Tracker](https://github.com/monarch-initiative/pyphetools/issues){:target="\_blank"}.
+
diff --git a/docs/index.rst b/docs/index.rst
deleted file mode 100644
index 2cffb6af..00000000
--- a/docs/index.rst
+++ /dev/null
@@ -1,42 +0,0 @@
-.. _home:
-
-==============================
-Python GA4GH Phenopacket Tools
-==============================
-
-Python GA4GH Phenopacket Tools (pyphetools) is a Python package for working with 
-`GA4GH phenopackets <https://phenopacket-schema.readthedocs.io/en/latest/>`_. 
-
-
-
-Installation
-^^^^^^^^^^^^
-See :ref:`installation` for instructions on how to set up the package. 
-
-
-
-.. toctree::
-    :caption: Contents
-    :maxdepth: 1
-
-    installation
-    user-guide/index
-    apidocs/modules  
-    developers
-    modules
-    test
-    pyphetools
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
-
---------
-Feedback
---------
-
-The best place to leave feedback, ask questions, and report bugs is the `Pyphetools Issue Tracker <https://github.com/monarch-initiative/pyphetools/issues>`_.
-
diff --git a/docs/installation.md b/docs/installation.md
new file mode 100644
index 00000000..0c75bb1f
--- /dev/null
+++ b/docs/installation.md
@@ -0,0 +1,32 @@
+# Installation of pyphetools
+
+
+pyphetools is available as a [PyPI package](https://pypi.org/project/pyphetools/){:target="\_blank"}. 
+
+Most users should install the latest version (the following example creates a virtual environment).
+Note that depending on your system it will be necessary to update pip to be able to install pyphetools.
+
+```bash title="setting up a virtual environment"
+python3 -m venv ppt_env
+source ppt_env/bin/activate
+pip install --upgrade pip
+```
+
+To work with the notebooks in this repository, it may be desirable to install the latest local version
+
+```bash title="installing pyphetools"
+source ppt_env/bin/activate
+pip install -e .
+```
+
+To use the kernel in notebooks, enter the following
+
+```bash title="installing jupyter and running pyphetools in a notebook"
+pip install jupyter ipykernel
+python -m ipykernel install --name "ppt_env" --display-name "ppt_env"
+jupyter-notebook
+```
+
+The last command will open a jupyter. Create or open a notebook and set the kernel to **ppt_env**.
+
+
diff --git a/docs/installation.rst b/docs/installation.rst
deleted file mode 100644
index ae797f2e..00000000
--- a/docs/installation.rst
+++ /dev/null
@@ -1,39 +0,0 @@
-.. _installation:
-
-==========================
-Installation of pyphetools
-==========================
-
-pyphetools is available as a `PyPI package <https://pypi.org/project/pyphetools/>`_. 
-
-Most users should install the latest version (the following example creates a virtual environment).
-Note that depending on your system it will be necessary to update pip to be able to install pyphetools.
-
-.. code-block:: shell
-   :linenos:
-
-   python3 -m venv ppt_env
-   source ppt_env/bin/activate
-   pip install --upgrade pip
-   pip install pyphetools
-
-To work with the notebooks in this repository, it may be desirable to install the latest local version
-
-.. code-block:: shell
-   :linenos:
-
-   source ppt_env/bin/activate
-   pip install -e .
-
-
-To use the kernel in notebooks, enter the following
-
-.. code-block:: shell
-   :linenos:
-
-   pip install jupyter
-   python -m ipykernel install --name "ppt_env" --display-name "ppt_env"
-   cd notebooks
-   jupyter-notebook
-
-
diff --git a/docs/user-guide/cohort_encoder.md b/docs/user-guide/cohort_encoder.md
new file mode 100644
index 00000000..bd1dd50b
--- /dev/null
+++ b/docs/user-guide/cohort_encoder.md
@@ -0,0 +1,38 @@
+# CohortEncoder
+
+This class coordinates the extract-transform-load (ETL) operations for a cohort, usually taken from 
+a table in a publication or supplemental file. It is intended to be used with the ColumnMappers to map
+each relevant column of the table.
+
+
+
+
+```python title="CohortEncoder constructor"
+pmid = "PMID:30612693"
+encoder = CohortEncoder(df=dft, hpo_cr=hpo_cr, column_mapper_d=column_mapper_d, 
+                      individual_column_name="patient_id", 
+                      agemapper=ageMapper, 
+                      sexmapper=sexMapper,
+                      metadata=metadata,
+                      variant_mapper=varMapper,
+                      pmid=pmid)
+disease_id = "OMIM:618443"
+disease_label = "Neurodevelopmental disorder with or without variable brain abnormalities"
+encoder.set_disease(disease_id=disease_id, label=disease_label)
+```
+
+### Display a phenopacket
+
+Optionally, it can be useful to displayand manually assess a phenopackets
+
+```python title="Display a phenopacket"
+individuals = encoder.get_individuals()
+i1 = individuals[0]
+phenopacket1 = i1.to_ga4gh_phenopacket(metadata=metadata.to_ga4gh())
+json_string = MessageToJson(phenopacket1)
+print(json_string)
+```
+
+
+
+
diff --git a/docs/user-guide/cohort_encoder.rst b/docs/user-guide/cohort_encoder.rst
deleted file mode 100644
index c0985596..00000000
--- a/docs/user-guide/cohort_encoder.rst
+++ /dev/null
@@ -1,37 +0,0 @@
-.. _cohort_encoder:
-
-=============
-CohortEncoder
-=============
-
-This class coordinates the extract-transform-load (ETL) operations for a cohort, usually taken from 
-a table in a publication or supplemental file. It is intended to be used with the ColumnMappers to map
-each relevant column of the table.
-
-
-
-.. code-block:: python
-  :linenos:
-
-  pmid = "PMID:30612693"
-  encoder = CohortEncoder(df=dft, hpo_cr=hpo_cr, column_mapper_d=column_mapper_d, 
-                          individual_column_name="patient_id", 
-                          agemapper=ageMapper, 
-                          sexmapper=sexMapper,
-                          metadata=metadata,
-                          variant_mapper=varMapper,
-                          pmid=pmid)
-  disease_id = "OMIM:618443"
-  disease_label = "Neurodevelopmental disorder with or without variable brain abnormalities"
-  encoder.set_disease(disease_id=disease_id, label=disease_label)
-  # optionally get the objects and display the phenopackets, for debugging
-  individuals = encoder.get_individuals()
-  i1 = individuals[0]
-  phenopacket1 = i1.to_ga4gh_phenopacket(metadata=metadata.to_ga4gh())
-  json_string = MessageToJson(phenopacket1)
-  print(json_string)
-  # output all encoded phenopackets
-  output_directory = "phenopackets"
-  encoder.output_phenopackets(outdir=output_directory)
-
-
diff --git a/docs/user-guide/constant_column_mapper.md b/docs/user-guide/constant_column_mapper.md
new file mode 100644
index 00000000..652fa7e1
--- /dev/null
+++ b/docs/user-guide/constant_column_mapper.md
@@ -0,0 +1,30 @@
+# ConstantColumnMapper
+
+
+Column mapper for cases where all individuals in a cohort have a certain phenotypic abnormality. If the excluded argument is set to True,
+then the abnormality was excluded in all individuals. This mapper is a shortcut that appears to be useful for some supplemental files.
+
+
+
+```python title="ConstantColumnMapper constructor"
+hp_id =  "HP:0031956"
+hp_label = "Elevated circulating aspartate aminotransferase concentration"
+mapper = ConstantColumnMapper(hpo_id=hp_id, hpo_label=hp_label)
+hp_term_list = mapper.map_cell("name of column")
+```
+
+
+Replace "name of column" with the actual column name in the input table.
+
+In this case, **hp_term_list** contains a single term corresponding to the indicated HP term (regardless of the contents of the cell). If this 
+mapper is used with the CohortMapper, then all individuals in the cohort will be annotated to the term.
+
+The following code is used if the phenotypic abnormality was explicitly excluded in all individuals in the cohort.
+
+
+```python title="ConstantColumnMapper constructor"
+hp_id =  "HP:0031956"
+hp_label = "Elevated circulating aspartate aminotransferase concentration"
+mapper = ConstantColumnMapper(hpo_id=hp_id, hpo_label=hp_label, excluded=True)
+hp_term_list = mapper.map_cell("name of column)
+```
diff --git a/docs/user-guide/constant_column_mapper.rst b/docs/user-guide/constant_column_mapper.rst
deleted file mode 100644
index dcb70322..00000000
--- a/docs/user-guide/constant_column_mapper.rst
+++ /dev/null
@@ -1,33 +0,0 @@
-.. _custom_column_mapper:
-
-====================
-ConstantColumnMapper
-====================
-
-Column mapper for cases where all individuals in a cohort have a certain phenotypic abnormality. If the excluded argument is set to True,
-then the abnormality was excluded in all individuals. This mapper is a shortcut that appears to be useful for some supplemental files.
-
-
-
-.. code-block:: python
-  :linenos:
-
-  hp_id =  "HP:0031956"
-  hp_label = "Elevated circulating aspartate aminotransferase concentration"
-  mapper = ConstantColumnMapper(hpo_id=hp_id, hpo_label=hp_label)
-  hp_term_list = mapper.map_cell("n/a")
-
-
-In this case, ``hp_term_list`` contains a single term corresponding to the indicated HP term (regardless of the contents of the cell). If this 
-mapper is used with the CohortMapper, then all individuals in the cohort will be annotated to the term.
-
-The following code is used if the phenotypic abnormality was explicitly excluded in all individuals in the cohort.
-
-.. code-block:: python
-  :linenos:
-
-  hp_id =  "HP:0031956"
-  hp_label = "Elevated circulating aspartate aminotransferase concentration"
-  mapper = ConstantColumnMapper(hpo_id=hp_id, hpo_label=hp_label, excluded=True)
-  hp_term_list = mapper.map_cell("n/a")
-
diff --git a/docs/user-guide/custom_column_mapper.md b/docs/user-guide/custom_column_mapper.md
new file mode 100644
index 00000000..43696495
--- /dev/null
+++ b/docs/user-guide/custom_column_mapper.md
@@ -0,0 +1,30 @@
+# CustomColumnMapper
+
+
+Column mapper for concept recognition (CR) augmented by custom maps for
+concepts missed by automatic CR.
+
+This column mapper should be used for columns that contain free text representing multiple
+different phenotypic abnormalities. As a rule, most of these will be captured by
+text mining (concept recognition). We use the ``preview_column`` function to assess
+the performance of the mapper, and if concepts are missed, they can be added
+using the optional ``custom_map_d`` argument. In some cases, concept recognition picks up terms that we deem to be
+false positive or irrelevant. In this case, we can add the strings to the optional
+``excluded_set`` argument to cause them to be skipped by the mapper.
+
+
+
+```python title="ConstantColumnMapper constructor"
+prenatal_custom_map = {'agenesis of the corpus callosum': 'Agenesis of corpus callosum',
+                     'IUGR': 'Intrauterine growth retardation',
+                     'small cerebellum':'Cerebellar hypoplasia',
+                     'vsd': 'Ventricular septal defect',
+                    }
+excluded = {'maternal asthma'}
+prenatalMapper = CustomColumnMapper(concept_recognizer=hpo_cr,
+                                  custom_map_d=prenatal_custom_map,
+                                  excluded_set=excluded)
+prenatalMapper.preview_column(dft['Prenatal complications'])
+```
+
+Note that 'Prenatal complications' corresponds to the column name in the input file.
\ No newline at end of file
diff --git a/docs/user-guide/custom_column_mapper.rst b/docs/user-guide/custom_column_mapper.rst
deleted file mode 100644
index ae53b336..00000000
--- a/docs/user-guide/custom_column_mapper.rst
+++ /dev/null
@@ -1,32 +0,0 @@
-.. _custom_column_mapper_rst:
-
-==================
-CustomColumnMapper
-==================
-
-Column mapper for concept recognition (CR) augmented by custom maps for
-concepts missed by automatic CR.
-
-This column mapper should be used for columns that contain free text representing multiple
-different phenotypic abnormalities. As a rule, most of these will be captured by
-text mining (concept recognition). We use the ``preview_column`` function to assess
-the performance of the mapper, and if concepts are missed, they can be added
-using the optional ``custom_map_d`` argument. In some cases, concept recognition picks up terms that we deem to be
-false positive or irrelevant. In this case, we can add the strings to the optional
-``excluded_set`` argument to cause them to be skipped by the mapper.
-
-
-.. code-block:: python
-  :linenos:
-
-  prenatal_custom_map = {'agenesis of the corpus callosum': 'Agenesis of corpus callosum',
-                         '\nIUGR': 'Intrauterine growth retardation',
-                         'small cerebellum':'Cerebellar hypoplasia',
-                         'vsd': 'Ventricular septal defect',
-                        }
-  excluded = {'maternal asthma'}
-  prenatalMapper = CustomColumnMapper(concept_recognizer=hpo_cr,
-                                      custom_map_d=prenatal_custom_map,
-                                      excluded_set=excluded)
-  prenatalMapper.preview_column(dft['Prenatal complications'])
-
diff --git a/docs/user-guide/index.rst b/docs/user-guide/index.rst
deleted file mode 100644
index 935dde43..00000000
--- a/docs/user-guide/index.rst
+++ /dev/null
@@ -1,27 +0,0 @@
-.. _rstuser-guide:
-
-==========
-User guide
-==========
-
-pyphetools is designed to be used in Jupyter notebook environments to encode tabular data as collections
-of `GA4GH phenopackets <https://phenopacket-schema.readthedocs.io/en/latest/>`_. See the notebooks on the 
-project `GitHub repository <https://github.com/monarch-initiative/pyphetools>`_ or in the 
-`phenopacket-store repo <https://github.com/monarch-initiative/phenopacket-store>`_ for detailed examples.
-The pages in this folder provide high-level explanations for the most important classes of pyphetools that should
-be sufficient for most users of the library. The API documentation provides additional details for developers.
-
-
-
-.. toctree::
-  :maxdepth: 1
-  :caption: Contents:
-
-  tutorial
-  cohort_encoder
-  constant_column_mapper
-  custom_column_mapper
-  option_column_mapper
-  simple_column_mapper
-  variant_column_mapper
-
diff --git a/docs/user-guide/intro.md b/docs/user-guide/intro.md
new file mode 100644
index 00000000..a3033d61
--- /dev/null
+++ b/docs/user-guide/intro.md
@@ -0,0 +1,29 @@
+# User guide
+
+
+pyphetools is designed to be used in Jupyter notebook environments to encode tabular data as collections
+of [GA4GH phenopackets](https://phenopacket-schema.readthedocs.io/en/latest/>). 
+See the notebooks on the 
+project [GitHub repository](https://github.com/monarch-initiative/pyphetools).
+For a comprehensive collection of notebooks created with pyphetools, see the 
+[phenopacket-store repo](https://github.com/monarch-initiative/phenopacket-store).
+
+The pages in this user guide provide high-level explanations for the most important classes of 
+pyphetools that should  be sufficient for most users of the library. 
+The API documentation provides additional 
+details for developers.
+
+
+
+.. toctree::
+  :maxdepth: 1
+  :caption: Contents:
+
+  tutorial
+  cohort_encoder
+  constant_column_mapper
+  custom_column_mapper
+  option_column_mapper
+  simple_column_mapper
+  variant_column_mapper
+
diff --git a/docs/user-guide/option_column_mapper.rst b/docs/user-guide/option_column_mapper.md
similarity index 56%
rename from docs/user-guide/option_column_mapper.rst
rename to docs/user-guide/option_column_mapper.md
index b732aa29..abd285ad 100644
--- a/docs/user-guide/option_column_mapper.rst
+++ b/docs/user-guide/option_column_mapper.md
@@ -1,22 +1,18 @@
-.. _option_column_mapper:
+# OptionColumnMapper
 
-==================
-OptionColumnMapper
-==================
 
 Mapper to be used if the column has a set of defined items but text mining is not required.
 
-.. code-block:: python
-  :linenos:
-
-  other_d = {
+```python title="OptionColumnMapper constructor"
+other_d = {
     "HP": ["High palate", "HP:0000218"],
     "D": ["Dolichocephaly", "HP:0000268"],
     "En": ["Deeply set eye", "HP:0000490"], # i.e., Enophthalmus
     "DE": ["Dural ectasia", "HP:0100775"],
     "St": ["Striae distensae", "HP:0001065"]
-  }
-  otherMapper = OptionColumnMapper(concept_recognizer=hpo_cr, option_d=other_d)
+}
+otherMapper = OptionColumnMapper(concept_recognizer=hpo_cr, option_d=other_d)
+```
 
 This mapper will recognize ``HP`` as well as ``HP,D,St``. The mapper interprets
 ``,``,  ``;``, ``|``, and ``/`` as delimiters. Note that the value of the dictionary
@@ -26,36 +22,36 @@ label of the HPO term.
 If text-mining is required, use the :ref:`custom_column_mapper`.
 
 
-Shortcut to creating option mapper objects
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+## Shortcut to creating option mapper objects
+
 
 It is possible to create the dictionaries used by the OptionColumnMapper by hand.
 However, the following command will generate a code-template from which users
 can copy and adapt code for relevant columns.
 
-.. code-block:: python
-   :linenos:
-
-    dft = ... #  Pandas DataFrame with columns representing clinical data
-    output = OptionColumnMapper.autoformat(df=dft, concept_recognizer=hpo_cr)
-    print(output)
-
-    post_fossa_d = {'Mega cisterna magna': 'Enlarged cisterna magna',
-                    'Normal': 'PLACEHOLDER',
-                    'Mega cistema magna': 'PLACEHOLDER'}
-    post_fossaMapper = OptionColumnMapper(concept_recognizer=hpo_cr, option_d=post_fossa_d)
-    post_fossaMapper.preview_column(df['Post fossa']))
-    column_mapper_d['Post fossa'] = post_fossaMapper
-
-    pituitary_d = {'Normal': 'PLACEHOLDER'}
-    pituitaryMapper = OptionColumnMapper(concept_recognizer=hpo_cr, option_d=pituitary_d)
-    pituitaryMapper.preview_column(df['Pituitary']))
-    column_mapper_d['Pituitary'] = pituitaryMapper
-    (...)
+```python title="OptionColumnMapper shortcut"
+dft = ... #  Pandas DataFrame with columns representing clinical data
+output = OptionColumnMapper.autoformat(df=dft, concept_recognizer=hpo_cr)
+print(output)
+
+post_fossa_d = {'Mega cisterna magna': 'Enlarged cisterna magna',
+                'Normal': 'PLACEHOLDER',
+                'Mega cistema magna': 'PLACEHOLDER'}
+post_fossaMapper = OptionColumnMapper(concept_recognizer=hpo_cr, option_d=post_fossa_d)
+post_fossaMapper.preview_column(df['Post fossa']))
+column_mapper_d['Post fossa'] = post_fossaMapper
+
+pituitary_d = {'Normal': 'PLACEHOLDER'}
+pituitaryMapper = OptionColumnMapper(concept_recognizer=hpo_cr, option_d=pituitary_d)
+pituitaryMapper.preview_column(df['Pituitary']))
+column_mapper_d['Pituitary'] = pituitaryMapper
+(...)
+```
 
 For instance, in the above example, there is a column called `Post fossa` in the DataFrame dft. The cell contents
 for the rows of the column contained several strings that we might want to map. `Enlarged cisterna magna` was
-recognized as the label of the HPO term `Enlarged cisterna magna (HP:0002280) <https://hpo.jax.org/app/browse/term/HP:0002280>`_.
+recognized as the label of the HPO term 
+[Enlarged cisterna magna (HP:0002280)](https://hpo.jax.org/app/browse/term/HP:0002280).
 We would remove the label 'Normal' (and possible code it as excluded using other commands). The 
 string `Mega cistema magna` is clearly a spelling error in the original data, and so we can map it
 to the string `Enlarged cisterna magna` (replace the PLACEHOLDER) so that the string will also be mapped to the HPO term.
diff --git a/docs/user-guide/simple_column_mapper.rst b/docs/user-guide/simple_column_mapper.md
similarity index 64%
rename from docs/user-guide/simple_column_mapper.rst
rename to docs/user-guide/simple_column_mapper.md
index 0862e649..4a6fdec1 100644
--- a/docs/user-guide/simple_column_mapper.rst
+++ b/docs/user-guide/simple_column_mapper.md
@@ -1,8 +1,5 @@
-.. _simple_column_mapper:
+# SimpleColumnMapper
 
-==================
-SimpleColumnMapper
-==================
 
 ColumnMapper for columns that contain information about a single phenotypic abnormality only.
 This kind of ColumnMapper should be used for columns that can be representing by one HPO term
@@ -11,39 +8,44 @@ observed, symbols such as "-", "N", "no" indicating that the abnormality was exp
 and (optionally) symbols indicating that the abnormality was not measured or assessed.
 
 For instance, the following mapper would generate a phenotypic feature for
-`Global developmental delay <https://hpo.jax.org/app/browse/term/HP:0001263>`_ if the
+[Global developmental delay](https://hpo.jax.org/app/browse/term/HP:0001263){:target="\_blank"} if the
 column contains "yes" (observed) and would call it as excluded if the column contains "no".
 For any other text or for an empty cell, the feature would be called as not measured (and would
 not be included in the phenopacket).
 
-.. code-block:: python
-  :linenos:
 
+```python title="SimpleColumnMapper constructor"
   ddMapper = SimpleColumnMapper(hpo_id='HP:0001263',
     hpo_label='Global developmental delay',
     observed='yes',
     excluded='no')
+```
+
 
-The constructor also has an optional ``constant`` argument - if set to true, the all patients are
-assigned the HPO term in question.
 
 It can be convenient to add multiple SimpleColumnMappers at the same time. The following function enables this.
 
 
-.. code-block:: python
-  :linenos:
 
-  items = {
+```python title="Creating multiple SimpleColumnMapper objects at once"
+## Note that we previously have created an HPO Concept Recognizer object
+parser = HpoParser()
+hpo_cr = parser.get_hpo_concept_recognizer()
+##
+column_mapper_d = {}
+items = {
     'regression': ["Developmental regression","HP:0002376"],
     'autism': ['Autism', 'HP:0000717'],
     'hypotonia': ['Hypotonia', 'HP:0001252'],
     'movement disorder': ['Abnormality of movement', 'HP:0100022'],
-    'CVI': ['Cerebral visual impairment', 'HP:0100704'], # CVI stands for Cortical visual impairment HP:0100704
+    'CVI': ['Cerebral visual impairment', 'HP:0100704'], 
     'seizures': ['Seizure','HP:0001250'],
     'DD': ['Global developmental delay', 'HP:0001263']
-  }
-  item_column_mapper_d = hpo_cr.initialize_simple_column_maps(column_name_to_hpo_label_map=items, observed='yes',
-    excluded='no')
-  # Transfer to column_mapper_d
-  for k, v in item_column_mapper_d.items():
+}
+item_column_mapper_d = hpo_cr.initialize_simple_column_maps(column_name_to_hpo_label_map=items, 
+                            observed='yes',
+                            excluded='no')
+# Transfer to column_mapper_d
+for k, v in item_column_mapper_d.items():
     column_mapper_d[k] = v
+```
diff --git a/docs/user-guide/threshold_column_mapper.rst b/docs/user-guide/threshold_column_mapper.md
similarity index 52%
rename from docs/user-guide/threshold_column_mapper.rst
rename to docs/user-guide/threshold_column_mapper.md
index 4f74316e..2eb4a74e 100644
--- a/docs/user-guide/threshold_column_mapper.rst
+++ b/docs/user-guide/threshold_column_mapper.md
@@ -1,8 +1,5 @@
-.. _threshold_column_mapper:
+# ThresholdColumnMapper
 
-=====================
-ThresholdColumnMapper
-=====================
 
 
 This mapper can be used for columns that have numerical data whereby being above or below a certain threshold is abnormal and 
@@ -10,36 +7,36 @@ can be represented by an HPO term. For instance, if "Age at head control (months
 
 
 
-.. code-block:: python
-  :linenos:
-
-  headLagMapper = ThresholdedColumnMapper(hpo_id="HP:0032988", hpo_label="Persistent head lag", 
-                                        threshold=4, call_if_above=True)
-  headLagMapper.preview_column(dft["Age at head control (months)"])
-
+```python title="ThresholdedColumnMapper constructor"
+headLagMapper = ThresholdedColumnMapper(hpo_id="HP:0032988", 
+                                        hpo_label="Persistent head lag", 
+                                        threshold=4, 
+                                        call_if_above=True)
+headLagMapper.preview_column(dft["Age at head control (months)"])
+```
 
 This might lead to a result such as the following, in which only the individual in the fourth row required more than 4 months to display head control.
 
 
-+-----------------------------------+----------+
+
 | term                              | status   |
-+===================================+==========+
+| :---------------------------------|----------|
 | Persistent head lag (HP:0032988)  | excluded |
 | Persistent head lag (HP:0032988)  | excluded | 
 | Persistent head lag (HP:0032988)  | excluded |
 | Persistent head lag (HP:0032988)  | observed |
 | Persistent head lag (HP:0032988)  | excluded |  
-+-----------------------------------+----------+
 
 
 
-ThresholdedColumnMapper - special code
-######################################
+### ThresholdedColumnMapper - special cases
 
 In some cases, phrases such as 'not attained' are used to denote that a child has not attained a certain milestone at the time of last examination and this this constitutes an abnormal finding. In this case, the optional argument ''observed_code'' should be used.
 
-.. code-block:: python
-  :linenos:
-
-  delayedSittingMapper =  ThresholdedColumnMapper(hpo_id="HP:0025336", hpo_label="Delayed ability to sit", 
-                                        threshold=9, call_if_above=True, observed_code='Not acquired')
+```python title="ThresholdedColumnMapper special cases"
+delayedSittingMapper =  ThresholdedColumnMapper(hpo_id="HP:0025336", 
+                                                hpo_label="Delayed ability to sit", 
+                                                threshold=9, 
+                                                call_if_above=True, 
+                                                observed_code='Not acquired')
+```
diff --git a/docs/user-guide/tutorial.rst b/docs/user-guide/tutorial.md
similarity index 53%
rename from docs/user-guide/tutorial.rst
rename to docs/user-guide/tutorial.md
index 69b1d21a..819ca210 100644
--- a/docs/user-guide/tutorial.rst
+++ b/docs/user-guide/tutorial.md
@@ -1,112 +1,124 @@
-.. _tutorial:
+# Tutorial
 
-====================
-pyphetools: Tutorial
-====================
 
-The goal of the pyphetools library is to provide a software framework for transforming tabular data about cohorts with rare of common disease into a collection 
-of `GA4GH phenopackets <https://phenopacket-schema.readthedocs.io/en/latest/>`_. We have applied to library to extract phenopackets from tables provided as  
-supplemental files of publications describing cohorts of individuals with a rare disease (Excel, tab or comma-separated value files, and even files copied into a 
+The goal of the pyphetools library is to provide a software framework for transforming tabular 
+data about cohorts with rare of common disease into a collection 
+of [GA4GH phenopackets](https://phenopacket-schema.readthedocs.io/en/latest/){:target="\_blank"}. We have applied to library 
+to extract phenopackets from tables provided as  
+supplemental files of publications describing cohorts of individuals with a rare disease 
+(Excel, tab or comma-separated value files, and even files copied into a 
 spreadsheet application from the original PDF file of the article).
 
 The best way to get a feeling for how to work with pyphetools is to examine the various notenooks in the 
-`phenopacket-store <https://github.com/monarch-initiative/phenopacket-store>`_ repository.
+[phenopacket-store](https://github.com/monarch-initiative/phenopacket-store){:target="\_blank"} repository.
 
 This tutorial provides some general tips for how to use the library. The library is intended to be used in a Jupyter notebook environment so that users can check intermediate results.
 There are many ways of setting this up, but here is one that we often use.
 
 
-.. code-block:: bash
-  :linenos:
 
-  python3 -m venv your_env
-  source your_env/bin/activiate
-  pip install --upgrade pip
-  pip install pyphetools
-  pip install jupyter ipykernel
-  python3 -m ipykernel install --name your_env --user
-  jupyter-notebook
+```bash title="installing jupyter and running pyphetools in a notebook"
+python3 -m venv your_env
+source your_env/bin/activiate
+pip install --upgrade pip
+pip install pyphetools
+pip install jupyter ipykernel
+python3 -m ipykernel install --name your_env --user
+jupyter-notebook
+```
 
-The virtual environment (here `your_env`) can be named as desired. The last line opens a Jupyter Notebook page; create a new Notebook and choose the kernel called `your_env` (or whatever you called it).
+The virtual environment (here *your_env*) can be named as desired. The last line opens a Jupyter Notebook page; 
+create a new Notebook and choose the kernel called *your_env* (or whatever you called it).
 
 
 
-Importing necessary packages
-############################
+### Importing necessary packages
 
-Most notebooks will want to first import all necessary packages. It is helpful to print out the version used (see the last two lines) in case of errors or feature requests.
 
+Most notebooks will want to first import all necessary packages. It is helpful to print out the version
+used (see the last two lines) in case of errors or feature requests.
 
-.. code-block:: python
-  :linenos:
 
-  import phenopackets as php
-  from google.protobuf.json_format import MessageToDict, MessageToJson
-  from google.protobuf.json_format import Parse, ParseDict
-  import pandas as pd
-  import math
-  from csv import DictReader
-  pd.set_option('display.max_colwidth', None) # show entire column contents, important!
-  from collections import defaultdict
-  import re
-  from pyphetools.creation import *
-  from pyphetools.output import PhenopacketTable
-  import importlib.metadata
-  __version__ = importlib.metadata.version("pyphetools")
-  print(f"Using pyphetools version {__version__}")
+```python title="imports"
+import phenopackets as php
+from google.protobuf.json_format import MessageToDict, MessageToJson
+from google.protobuf.json_format import Parse, ParseDict
+import pandas as pd
+import math
+from csv import DictReader
+pd.set_option('display.max_colwidth', None) # show entire column contents, important!
+from collections import defaultdict
+import re
+from pyphetools.creation import *
+from pyphetools.visualization import PhenopacketTable
+print(f"pyphetools version {pyphetools.__version__}")
+```
 
 
 
 
-Import the Human Phenotype Ontology (HPO) file
-##############################################
+### Import the Human Phenotype Ontology (HPO) file
+
 
 It is useful to import the HPO file and create the MetaData object (which records your `ORCID <https://orcid.org/>`_ id and the version of the HPO used) in one step.
 
-.. code-block:: python
-  :linenos:
+```python title="HPO and MetaData"
+parser = HpoParser()
+hpo_cr = parser.get_hpo_concept_recognizer()
+hpo_version = parser.get_version()
+metadata = MetaData(created_by="ORCID:0000-0002-0736-9199")
+metadata.default_versions_with_hpo(version=hpo_version)
+```
+
+It is often useful to display the title and PubMed identifier of the publication from which the data come. 
+Simply replace the above code with the following.
+
+```python title="HPO and MetaData (with title and PMID)"
+parser = HpoParser()
+hpo_cr = parser.get_hpo_concept_recognizer()
+hpo_version = parser.get_version()
+PMID = "PMID:24736735"
+title = "New insights into genotype-phenotype correlation for GLI3 mutations"
+metadata = MetaData(created_by="ORCID:0000-0002-0736-9199", pmid=PMID, pubmed_title=title)
+metadata.default_versions_with_hpo(version=hpo_version)
+```
 
-  parser = HpoParser()
-  hpo_cr = parser.get_hpo_concept_recognizer()
-  hpo_version = parser.get_version()
-  metadata = MetaData(created_by="ORCID:0000-0002-0736-9199")
-  metadata.default_versions_with_hpo(version=hpo_version)
 
-The MetaData is a message of the GA4GH Phenopacket Schema. See the `GA4GH phenopackets documentation <https://phenopacket-schema.readthedocs.io/en/latest/>`_ for more details.
+The MetaData is a message of the GA4GH Phenopacket Schema. See the
+[GA4GH phenopackets documentation](https://phenopacket-schema.readthedocs.io/en/latest/){:target="\_blank"} for more details.
 
 
-Importing the data
-##################
+### Importing the data
+
 
 In general, we have taken the input data from Excel files or from CSV (command-separated value) files or TSV (tab-separated value files). Excel files can be imported using the following pandas command.
 
-.. code-block:: python
-  :linenos:
+```python title="Reading an Excel input file"
+df = pd.read_excel('some/path/my_supplement.xlsx')
+```
 
-  df = pd.read_excel('some/path/my_supplement.xlsx')
+Standard pandas functions are available to read CSV and TSV files. We refer to the [pandas documentation](https://pandas.pydata.org/) for  more details.
 
-Standard pandas functions are available to read CSV and TSV files. We refer to the `pandas documentation <https://pandas.pydata.org/>`_ for  more details.
 
+### Inspecting the input data
 
-Inspecting the input data
-#########################
 
 Users will need to carefully inspect the input table (e.g. a Supplemental file) and determine which columns or rows contain the individual id, age, and sex, the variants, and clinical information that can be encoded using HPO terms.
 We recommand inspecting the first several rows using
 
-.. code-block:: python
-  :linenos:
-
-  df.head()
+```python title="Inspecting the data"
+df.head()
+```
 
 It is also useful to look at the column names.
 
-.. code-block:: python
-  :linenos:
+```python title="Inspecting the column names"
+df.columns
+```
 
-  df.columns
 
 
+## Clinical columns 
 pyphetools expects to get a dictionary whose keys correspond to the column names used by the pandas DataFrame, 
 and the values are the corresponding ColumnMapper objects. pyphetools offers different types of ColumnMapper objects, whose goal is to 
 encode the id, age, sex, variants, and clinical information encoded by HPO terms. We first create a dictionary whose keys should be the 
@@ -114,28 +126,25 @@ names (strings) of the columns of the table and whose values are the correspondi
 want to map. Note that it is not necessary to map each column of a table.
 
 
-Clinical columns 
-################
-
 Data with clinical columns in typical supplemental files often have one of three forms.
 
 
-1. Simple. The column header is a string such as 'ID' that corresponds to an HPO term (`Intellectual disability HP:0001249 <https://hpo.jax.org/app/browse/term/HP:0001249>`_) and each cell has a symbol such as 
+1. Simple. The column header is a string such as 'ID' that corresponds to an HPO term 
+2. ([Intellectual disability HP:0001249](https://hpo.jax.org/app/browse/term/HP:0001249){:target="\_blank"} and each cell has a symbol such as 
 'Y', 'y', '+', 'yes', ''n', '-', etc. to indicate whether the feature was present in the individual specified by the row.  See :ref:`simple_column_mapper` for more information about how to work with this kind of column.
-2. Options. Some columns contain several strings, each of which corresponds to a specific HPO term. For instance, a columns such as 'severity of ID' with entries such as `mild`, `moderate`, `severe` would correspond to HPO terms for 
+3. Options. Some columns contain several strings, each of which corresponds to a specific HPO term. For instance, a columns such as 'severity of ID' with entries such as `mild`, `moderate`, `severe` would correspond to HPO terms for 
 `Intellectual disability, mild HP:0001256 <https://hpo.jax.org/app/browse/term/HP:0001256>`_, etc. See :ref:`option_column_mapper` for more information about how to work with this kind of column.
-3. Custom. This mapper is used for columns whose cells contain longer strings. We use a combination of text mining and specification of strings that were not matched by mining to extract HPO terms. See :ref:`custom_column_mapper_rst` for more information.
-4. Constant. This mapper can be used if all individuals diusplay the same feature. See :ref:`simple_column_mapper`.
-5. Threshold. This can be used for columns that have numerical data whereby being above or below a certain threshold is abnormal. See :ref:`threshold_column_mapper`.
+4. Custom. This mapper is used for columns whose cells contain longer strings. We use a combination of text mining and specification of strings that were not matched by mining to extract HPO terms. See :ref:`custom_column_mapper_rst` for more information.
+5. Constant. This mapper can be used if all individuals diusplay the same feature. See :ref:`simple_column_mapper`.
+6. Threshold. This can be used for columns that have numerical data whereby being above or below a certain threshold is abnormal. See :ref:`threshold_column_mapper`.
 
 
-Row-based vs column-based
-#########################
+## Row-based vs column-based
 
 pyphetools expects the rows to represent individuals. In some cases, input files represent individuals in columns. In this case, it is necessary to transpose the table before working with pyphetools.
 
 
-Converting to row-based format
+### Converting to row-based format
 
 To use pyphetools, we need to have the individuals represented as rows (one row per individual) and have the items of interest be encoded as column names. 
 The required transformations for doing this may be different for different input data, but often we will want to transpose the table (using the pandas transpose function) 
@@ -145,13 +154,12 @@ and set the column names of the new table to the zero-th row. After this, we dro
 
 Here is an example. Other examples can be found in several of the notebooks in phenopacket-store.
 
-.. code-block:: python
-  :linenos:
-
-  dft = df.transpose()
-  dft.columns = dft.iloc[0]
-  dft.drop(dft.index[0], inplace=True)
-  dft.head()
+```python title="Transforming from column-based to row-based format"
+dft = df.transpose()
+dft.columns = dft.iloc[0]
+dft.drop(dft.index[0], inplace=True)
+dft.head()
+```
 
 
 Another thing to look out for is whether the individuals (usually the first column) are regarded as the index of the table or as the first normal column.
@@ -159,13 +167,12 @@ If this is the case, it is easiest to create a new column with the contents of t
 An example follows -- we can now use 'patient_id' as the column name. It is easier to work with this than with the index column.
 
 
-.. code-block:: python
-  :linenos:
-
-  dft.index  # first check the index
-  dft['patient_id'] = dft.index  # Set the new column 'patient_id' to be identical to the contents of the index
-  dft.head() # check the transposed table
 
+```python title="creating column with patient identifiers"
+dft.index  # first check the index
+dft['patient_id'] = dft.index  # Set the new column 'patient_id' to be identical to the contents of the index
+dft.head() # check the transposed table
+```
 
 After this step is completed, the remaining steps to create phenopackets are the same as in the row-based notebook.
 
@@ -180,3 +187,4 @@ After this step is completed, the remaining steps to create phenopackets are the
 
 
 
+
diff --git a/docs/user-guide/variant_column_mapper.md b/docs/user-guide/variant_column_mapper.md
new file mode 100644
index 00000000..8641db1d
--- /dev/null
+++ b/docs/user-guide/variant_column_mapper.md
@@ -0,0 +1,41 @@
+# VariantColumnMapper
+
+TODO -- update
+
+ColumnMapper for columns that contain information about the variant(s) found in an individual.
+There are two main ways of using this class. If there is a column that contains an HGVS expression
+for the variant (without the transcript), then the transcript is indicated by the default_transcript argument.
+
+
+
+
+```python title="ThresholdedColumnMapper constructor"
+transcript='NM_015133.4'
+varMapper = VariantColumnMapper(assembly='hg38',
+                                variant_column_name='Transcript:NM_015133.4',
+                                transcript=transcript, 
+                                default_genotype='heterozygous')                        
+```
+The VariantColumnMapper is now ready to go to map HGVS expressions in the column ``Transcript:NM_015133.4``.
+
+
+
+
+##  Manual assignment of variants
+
+In some cases, other symbols are used, and then we create the Variant objects manually and assign them
+using a map.
+
+
+
+```python title="ThresholdedColumnMapper constructor"
+genome = 'hg38'
+default_genotype = 'heterozygous'
+transcript='NM_014159.7'
+varMapper = VariantColumnMapper(assembly=genome,column_name='Variant',
+                              transcript=transcript, default_genotype=default_genotype)
+variant_5218 = varMapper.map_cell('c.5218C>T')
+variant_5219 = varMapper.map_cell('c.5219G>A')
+variant_map = {"p.(Arg1740Trp)": variant_5218, 'p.(Arg1740Gln)': variant_5219}
+varMapper.set_variant_symbol_dictionary(variant_map)
+```
\ No newline at end of file
diff --git a/docs/user-guide/variant_column_mapper.rst b/docs/user-guide/variant_column_mapper.rst
deleted file mode 100644
index 84c9ffb7..00000000
--- a/docs/user-guide/variant_column_mapper.rst
+++ /dev/null
@@ -1,45 +0,0 @@
-.. _variant_column_mapper:
-
-===================
-VariantColumnMapper
-===================
-
-ColumnMapper for columns that contain information about the variant(s) found in an individual.
-There are two main ways of using this class. If there is a column that contains an HGVS expression
-for the variant (without the transcript), then the transcript is indicated by the default_transcript argument.
-
-
-
-.. code-block:: python
-  :linenos:
-
-  genome = 'hg38'
-  default_genotype = 'heterozygous'
-  transcript='NM_015133.4'
-  varMapper = VariantColumnMapper(assembly=genome,column_name='Transcript:NM_015133.4',
-                                transcript=transcript, genotype=default_genotype)
-
-The VariantColumnMapper is now ready to go to map HGVS expressions in the column ``Transcript:NM_015133.4``.
-
-
-
-
-Manual assignment of variants
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-In some cases, other symbols are used, and then we create the Variant objects manually and assign them
-using a map.
-
-
-
-.. code-block:: python
-  :linenos:
-
-  genome = 'hg38'
-  default_genotype = 'heterozygous'
-  transcript='NM_014159.7'
-  varMapper = VariantColumnMapper(assembly=genome,column_name='Variant',
-                                transcript=transcript, default_genotype=default_genotype)
-  variant_5218 = varMapper.map_cell('c.5218C>T')
-  variant_5219 = varMapper.map_cell('c.5219G>A')
-  variant_map = {"p.(Arg1740Trp)": variant_5218, 'p.(Arg1740Gln)': variant_5219}
-  varMapper.set_variant_symbol_dictionary(variant_map)
diff --git a/docs/user-guide/visualization.md b/docs/user-guide/visualization.md
new file mode 100644
index 00000000..a121c655
--- /dev/null
+++ b/docs/user-guide/visualization.md
@@ -0,0 +1,5 @@
+# Visualization
+
+
+
+todo describe Table Converter
\ No newline at end of file
diff --git a/docs/user-guide/visualization.rst b/docs/user-guide/visualization.rst
deleted file mode 100644
index ccab384d..00000000
--- a/docs/user-guide/visualization.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-.. _visualization:
-
-=============
-Visualization
-=============
-
-
-todo descrive Table Converter
\ No newline at end of file
diff --git a/mkdocs.yml b/mkdocs.yml
new file mode 100644
index 00000000..5badf8b5
--- /dev/null
+++ b/mkdocs.yml
@@ -0,0 +1,87 @@
+site_name: pyphetools
+
+theme:
+  name: "material"
+  features:
+    - navigation.tabs
+    - navigation.sections
+    - toc.integrate
+    - navigation.top
+    - search.suggest
+    - search.highlight
+    - content.tabs.link
+    - content.code.annotation
+    - content.code.copy
+    - content.code.select
+  language: en
+  palette:
+    - scheme: default
+      toggle:
+        icon: material/toggle-switch-off-outline
+        name: Switch to dark mode
+      primary: indigo
+      accent: white
+    - scheme: slate
+      toggle:
+        icon: material/toggle-switch
+        name: Switch to light mode
+      primary: teal
+      accent: lime
+
+
+nav:
+  - Home: 'index.md'
+  - Installation: 'installation.md'
+  - Developers: 'developers.md'
+  - User guide:
+    - Intro: 'user-guide/intro.md'
+    - Tutorial: 'user-guide/tutorial.md'
+    - Simple column mapper: 'user-guide/simple_column_mapper.md'
+    - Constant column mapper: 'user-guide/constant_column_mapper.md'
+    - Custom column mapper: 'user-guide/custom_column_mapper.md'
+    - Option column mapper: 'user-guide/option_column_mapper.md'
+    - Threshold column mapper: 'user-guide/threshold_column_mapper.md'
+    - Variant column mapper: 'user-guide/variant_column_mapper.md'
+    - Cohort encoder: 'user-guide/cohort_encoder.md'
+    - Visualization: 'user-guide/visualization.md'
+  - API: 'api.md'
+
+
+plugins:
+  - social
+  - search
+  - mkdocstrings
+
+
+extra:
+  social:
+    - icon: fontawesome/brands/github-alt
+      link: https://github.com/pnrobinson
+    - icon: fontawesome/brands/twitter
+      link: https://twitter.com/pnrobins
+    - icon: fontawesome/brands/linkedin
+      link: https://www.linkedin.com/in/peter-n-robinson-b7833811/
+
+
+markdown_extensions:
+  - pymdownx.highlight:
+      anchor_linenums: true
+  - pymdownx.inlinehilite
+  - pymdownx.snippets
+  - admonition
+  - pymdownx.arithmatex:
+      generic: true
+  - footnotes
+  - pymdownx.details
+  - pymdownx.superfences
+  - pymdownx.mark
+  - attr_list
+  - md_in_html
+  - tables
+  - pymdownx.emoji:
+      emoji_index: !!python/name:materialx.emoji.twemoji
+      emoji_generator: !!python/name:materialx.emoji.to_svg
+
+copyright: |
+  &copy; 2023 <a href="https://github.com/pnrobinson"  target="_blank" rel="noopener">Peter N Robinson</a>
+
diff --git a/notebooks/Example_1_(rowwise_table)_MAPK8IP3.ipynb b/notebooks/Example_1_(rowwise_table)_MAPK8IP3.ipynb
deleted file mode 100644
index 30921fe6..00000000
--- a/notebooks/Example_1_(rowwise_table)_MAPK8IP3.ipynb
+++ /dev/null
@@ -1,2076 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "id": "88225d96",
-   "metadata": {},
-   "source": [
-    "<h1>Creation of phenopackets from supplemental tables</h1>\n",
-    "<p>The Python Phenopackets Tools (pyphetools) library offers several functions for the creation, validation, and display of <a href=\"https://pubmed.ncbi.nlm.nih.gov/35705716/\" target=\"__blank\">GA4GH phenopackets</a>.</p>\n",
-    "<p>The main scope of pyphetools is to streamline the import of phenotypic and genotypic data from tables of data provided as supplemental material in the medical literature. pyphetools offers various functions to assess, convert, transform, and display such data. Functions are provided to cover many of the most commonly encountered patterns found in Supplemental files in the human genetics literature.</p>\n",
-    "<p>Let's take <a href=\"https://pubmed.ncbi.nlm.nih.gov/30612693/\" target=\"__blank\">Platzer K., et al. (2019) De Novo Variants in MAPK8IP3 Cause Intellectual Disability with Variable Brain Anomalies</a> as an example</p>\n",
-    "<p>pyphetools provides a convenient way of extracting HPO terms from typical tables presented in supplemental material, in which columns either contain yes/no/not-observed indications for a specific phenotypic feature or contain variously formated strings with one or multiple phenotypic features. pyphetools uses text mining to capture as many <a href=\"https://hpo.jax.org/app/\" target=\"__blank\">HPO</a> terms as possible and allows users to specific optional dictionaries that map words or phrases used in the table to the primary labels of HPO terms.</p>\n",
-    "<p>We recommend using Jupyter notebooks to perform the analysis so that it is easy to visualize results from intermediate steps. Once all data has been ingested, pyphetools exports one phenopacket for each individual in the cohort, ready for downstream analysis.</p>\n",
-    "<p>We recommend validating the generated phenopackets using <a href=\"http://phenopackets.org/phenopacket-tools/stable/cli.html\">phenopacket tools</a>.</p>"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 4,
-   "id": "4b730d47",
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Using pyphetools version 0.4.11\n"
-     ]
-    }
-   ],
-   "source": [
-    "import phenopackets as php\n",
-    "from google.protobuf.json_format import MessageToDict, MessageToJson\n",
-    "from google.protobuf.json_format import Parse, ParseDict\n",
-    "import pandas as pd\n",
-    "pd.set_option('display.max_colwidth', None) # show entire column contents, important!\n",
-    "from collections import defaultdict\n",
-    "from pyphetools.creation import *\n",
-    "import importlib.metadata\n",
-    "__version__ = importlib.metadata.version(\"pyphetools\")\n",
-    "print(f\"Using pyphetools version {__version__}\")"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "3b908768",
-   "metadata": {},
-   "source": [
-    "<h2>Importing HPO data</h2>\n",
-    "<p>pyphetools uses the <a href=\"https://hpo.jax.org/\">Human Phenotype Ontology (HPO)</a> to encode phenotypic features. The recommended way of doing this is to ingest the hp.json file using HpoParser, which in turn creates an HpoConceptRecognizer object. </p>\n",
-    "<p>The HpoParser can accept a <tt>hpo_json_file</tt> argument if you want to use a specific file. If the argument is not passed, it will download the latext hp.json file from the HPO GitHub site and store it in a new subdirectory called hpo_data. It will not download the file if the file is already downloaded.</p>\n",
-    "<p>The Phenopacket Schema also requires that the versions of the ontology and the identifier of the creator be specified. We recommend using an ORCID id, which can be done as follows.</p>"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 5,
-   "id": "c5b44b18",
-   "metadata": {
-    "scrolled": true
-   },
-   "outputs": [],
-   "source": [
-    "parser = HpoParser()\n",
-    "hpo_cr = parser.get_hpo_concept_recognizer()\n",
-    "hpo_version = parser.get_version()\n",
-    "metadata = MetaData(created_by=\"ORCID:0000-0002-0736-9199\")\n",
-    "metadata.default_versions_with_hpo(version=hpo_version)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "49b6cf4c",
-   "metadata": {},
-   "source": [
-    "<h2>Importing the supplemental table</h2>\n",
-    "<p>Supplemental Table S1 of the Platzer et al (2019) paper is an Excel file that is included in the data subfolder and contains Detailed Clinical Information for All Individuals with Causative De Novo Variants in MAPK8IP3. We need to read this from the original Excel file because some of the cells contain new-line symbols.</p>\n",
-    "<p>Here, we use the pandas library to import this file (note that the Python package called openpyxl must be installed to read Excel files with pandas, although the library does not need to be imported in this notebook). pyphetools expects a pandas DataFrame as input, and users can choose any input format available for pandas include CSV, TSV, and Excel, or can use any other method to transform their input data into a Pandas DataFrame before using pyphetools.</p>"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 6,
-   "id": "a748b70a",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "df = pd.read_excel('data/platzer_2019_supplement.xlsx')"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "bfc95891",
-   "metadata": {},
-   "source": [
-    "<h2>Stepwise encoding of the supplementary material</h2>\n",
-    "<p>pyphetools supports efficient and accurate HPO-encoding of typical supplementary tables that describe a cohort of \n",
-    "individuals found to have a certain disease. We recommend using the <tt>df.head()</tt> and the <tt>df.columns</tt> commands\n",
-    "to view the data and the column headers as follows.</p>"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 7,
-   "id": "d1abeea5",
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>Indvidual\\nin\\nmanuscript</th>\n",
-       "      <th>g.(hg19) Chr16:</th>\n",
-       "      <th>Transcript\\nNM_015133.4\\nc.</th>\n",
-       "      <th>p.</th>\n",
-       "      <th>origin</th>\n",
-       "      <th>genetic testing</th>\n",
-       "      <th>Sex</th>\n",
-       "      <th>age at last assesment</th>\n",
-       "      <th>prenatal period</th>\n",
-       "      <th>Exam at birth</th>\n",
-       "      <th>...</th>\n",
-       "      <th>neurological examination</th>\n",
-       "      <th>result of external MRI</th>\n",
-       "      <th>seizures</th>\n",
-       "      <th>Sz onset and Sz types</th>\n",
-       "      <th>AEDs used</th>\n",
-       "      <th>Sz outcome</th>\n",
-       "      <th>EEG</th>\n",
-       "      <th>Additional symptoms</th>\n",
-       "      <th>family history</th>\n",
-       "      <th>further results of genetic testing</th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>0</th>\n",
-       "      <td>1</td>\n",
-       "      <td>1756405</td>\n",
-       "      <td>c.65delG</td>\n",
-       "      <td>p.Gly22Alafs*3</td>\n",
-       "      <td>de novo</td>\n",
-       "      <td>TrioWES</td>\n",
-       "      <td>M</td>\n",
-       "      <td>14 y 8 m</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>41 weeks:\\nlength: 53.3 cm\\nweight: 3.941 kg\\nOFC: NA</td>\n",
-       "      <td>...</td>\n",
-       "      <td>ataxia</td>\n",
-       "      <td>mild cerebellar atrophy, hypointensity of the globi pallidi and substantia nigra, possible mild degree of abnormal iron or mineral deposition</td>\n",
-       "      <td>no</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>speech is ataxic but speaks in sentences/short phrases; attention issues, impulse control and emotional lability, OCD symptoms; recently developed scoliosis</td>\n",
-       "      <td>unremarkable</td>\n",
-       "      <td>NaN</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>1</th>\n",
-       "      <td>2</td>\n",
-       "      <td>1756419</td>\n",
-       "      <td>c.79G&gt;T</td>\n",
-       "      <td>p.Glu27*</td>\n",
-       "      <td>de novo</td>\n",
-       "      <td>SingleWES</td>\n",
-       "      <td>M</td>\n",
-       "      <td>4 y</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>length: 49 cm\\nweigth: 3215 g\\nOFC: 35 cm</td>\n",
-       "      <td>...</td>\n",
-       "      <td>ataxia</td>\n",
-       "      <td>normal</td>\n",
-       "      <td>no</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>pre-natal pelvi-ureteric junction stenosis (spontaneous resolution at 6 m)</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>2</th>\n",
-       "      <td>3</td>\n",
-       "      <td>1756451</td>\n",
-       "      <td>c.111C&gt;G</td>\n",
-       "      <td>p.Tyr37*</td>\n",
-       "      <td>de novo</td>\n",
-       "      <td>TrioWES</td>\n",
-       "      <td>M</td>\n",
-       "      <td>4 y</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>length: 20.5 in\\nweight: 8 lb 2 oz\\nOFC: NA</td>\n",
-       "      <td>...</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>Stable areas of T2 hyperintensity involving the central tegmental tracts</td>\n",
-       "      <td>no</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>Nystagmus</td>\n",
-       "      <td>unremarkable</td>\n",
-       "      <td>770 kb duplicaion of 20p12.3 on chromosome microarray</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>3</th>\n",
-       "      <td>4</td>\n",
-       "      <td>1798706</td>\n",
-       "      <td>c.1198G&gt;A</td>\n",
-       "      <td>p.Gly400Arg</td>\n",
-       "      <td>de novo</td>\n",
-       "      <td>TrioWES</td>\n",
-       "      <td>M</td>\n",
-       "      <td>7 y 6 m</td>\n",
-       "      <td>no prenatal care, no known problems</td>\n",
-       "      <td>32 weeks:\\nlength: NA,\\nweight: 4 lbs,\\nOFC: NA\\n\\nhad a 30 day hospital course</td>\n",
-       "      <td>...</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>no MRI done</td>\n",
-       "      <td>no</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>Left hearing loss; Dysmorphic features: hypertelorism inner canthal distance 4.3cm; low set prominent ears, slight overhangin columella, hypodontia; 5th finger clinodactyly and 5th finger brachydactylky; synophrys; Encopresis</td>\n",
-       "      <td>Mother with learning disorder; finished 11th grade; Father with ADHD and learning disorder; finished 9th grade; Full sister with learning disorder; Full sister no known problems; Full brother with learning disorder</td>\n",
-       "      <td>NaN</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>4</th>\n",
-       "      <td>5</td>\n",
-       "      <td>1810410</td>\n",
-       "      <td>c.1331T&gt;C</td>\n",
-       "      <td>p.Leu444Pro</td>\n",
-       "      <td>de novo</td>\n",
-       "      <td>TrioWES</td>\n",
-       "      <td>M</td>\n",
-       "      <td>10 y</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>40 weeks, length: 52 cm\\nweight:  3810 g\\nOFC: 36 cm</td>\n",
-       "      <td>...</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>perisylvian polymicrogyria</td>\n",
-       "      <td>yes</td>\n",
-       "      <td>10 y:\\none event of a generalized seizure</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>pathological EEG with normal age-related background activity (alpha-type), increased appearance of slowing over temporal and occipital regions</td>\n",
-       "      <td>no dysmorphism, small teeth, severe s-configured scoliosis of thoracic and lumbar spine</td>\n",
-       "      <td>NaN</td>\n",
-       "      <td>NaN</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "<p>5 rows × 29 columns</p>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "   Indvidual\\nin\\nmanuscript  g.(hg19) Chr16: Transcript\\nNM_015133.4\\nc.  \\\n",
-       "0                          1          1756405                    c.65delG   \n",
-       "1                          2          1756419                     c.79G>T   \n",
-       "2                          3          1756451                    c.111C>G   \n",
-       "3                          4          1798706                 c.1198G>A     \n",
-       "4                          5          1810410                   c.1331T>C   \n",
-       "\n",
-       "               p.   origin genetic testing Sex age at last assesment  \\\n",
-       "0  p.Gly22Alafs*3  de novo         TrioWES   M              14 y 8 m   \n",
-       "1        p.Glu27*  de novo       SingleWES   M                   4 y   \n",
-       "2        p.Tyr37*  de novo         TrioWES   M                   4 y   \n",
-       "3     p.Gly400Arg  de novo         TrioWES   M               7 y 6 m   \n",
-       "4     p.Leu444Pro  de novo         TrioWES   M                  10 y   \n",
-       "\n",
-       "                       prenatal period  \\\n",
-       "0                                  NaN   \n",
-       "1                                  NaN   \n",
-       "2                                  NaN   \n",
-       "3  no prenatal care, no known problems   \n",
-       "4                                  NaN   \n",
-       "\n",
-       "                                                                     Exam at birth  \\\n",
-       "0                            41 weeks:\\nlength: 53.3 cm\\nweight: 3.941 kg\\nOFC: NA   \n",
-       "1                                        length: 49 cm\\nweigth: 3215 g\\nOFC: 35 cm   \n",
-       "2                                      length: 20.5 in\\nweight: 8 lb 2 oz\\nOFC: NA   \n",
-       "3  32 weeks:\\nlength: NA,\\nweight: 4 lbs,\\nOFC: NA\\n\\nhad a 30 day hospital course   \n",
-       "4                             40 weeks, length: 52 cm\\nweight:  3810 g\\nOFC: 36 cm   \n",
-       "\n",
-       "   ... neurological examination  \\\n",
-       "0  ...                   ataxia   \n",
-       "1  ...                   ataxia   \n",
-       "2  ...                      NaN   \n",
-       "3  ...                      NaN   \n",
-       "4  ...                      NaN   \n",
-       "\n",
-       "                                                                                                                          result of external MRI  \\\n",
-       "0  mild cerebellar atrophy, hypointensity of the globi pallidi and substantia nigra, possible mild degree of abnormal iron or mineral deposition   \n",
-       "1                                                                                                                                         normal   \n",
-       "2                                                                       Stable areas of T2 hyperintensity involving the central tegmental tracts   \n",
-       "3                                                                                                                                    no MRI done   \n",
-       "4                                                                                                                     perisylvian polymicrogyria   \n",
-       "\n",
-       "  seizures                      Sz onset and Sz types AEDs used Sz outcome  \\\n",
-       "0       no                                        NaN       NaN        NaN   \n",
-       "1       no                                        NaN       NaN        NaN   \n",
-       "2       no                                        NaN       NaN        NaN   \n",
-       "3       no                                        NaN       NaN        NaN   \n",
-       "4      yes  10 y:\\none event of a generalized seizure       NaN        NaN   \n",
-       "\n",
-       "                                                                                                                                              EEG  \\\n",
-       "0                                                                                                                                             NaN   \n",
-       "1                                                                                                                                             NaN   \n",
-       "2                                                                                                                                             NaN   \n",
-       "3                                                                                                                                             NaN   \n",
-       "4  pathological EEG with normal age-related background activity (alpha-type), increased appearance of slowing over temporal and occipital regions   \n",
-       "\n",
-       "                                                                                                                                                                                                                 Additional symptoms  \\\n",
-       "0                                                                       speech is ataxic but speaks in sentences/short phrases; attention issues, impulse control and emotional lability, OCD symptoms; recently developed scoliosis   \n",
-       "1                                                                                                                                                         pre-natal pelvi-ureteric junction stenosis (spontaneous resolution at 6 m)   \n",
-       "2                                                                                                                                                                                                                          Nystagmus   \n",
-       "3  Left hearing loss; Dysmorphic features: hypertelorism inner canthal distance 4.3cm; low set prominent ears, slight overhangin columella, hypodontia; 5th finger clinodactyly and 5th finger brachydactylky; synophrys; Encopresis   \n",
-       "4                                                                                                                                            no dysmorphism, small teeth, severe s-configured scoliosis of thoracic and lumbar spine   \n",
-       "\n",
-       "                                                                                                                                                                                                           family history  \\\n",
-       "0                                                                                                                                                                                                            unremarkable   \n",
-       "1                                                                                                                                                                                                                     NaN   \n",
-       "2                                                                                                                                                                                                            unremarkable   \n",
-       "3  Mother with learning disorder; finished 11th grade; Father with ADHD and learning disorder; finished 9th grade; Full sister with learning disorder; Full sister no known problems; Full brother with learning disorder   \n",
-       "4                                                                                                                                                                                                                     NaN   \n",
-       "\n",
-       "                      further results of genetic testing  \n",
-       "0                                                    NaN  \n",
-       "1                                                    NaN  \n",
-       "2  770 kb duplicaion of 20p12.3 on chromosome microarray  \n",
-       "3                                                    NaN  \n",
-       "4                                                    NaN  \n",
-       "\n",
-       "[5 rows x 29 columns]"
-      ]
-     },
-     "execution_count": 7,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "df.head()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "4efcd9a8",
-   "metadata": {},
-   "source": [
-    "<h3>Step 1: Determine the columns of interest</h3>\n",
-    "<p>Typically, some but not all columns of Supplemental tables include clinical phenotypic features that can be encoded using HPO. Inspect the table using the pandas <tt>head()</tt> function or the <tt>columns</tt> attribute and decide which columns to encode</p>"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 8,
-   "id": "80bfbdbf",
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "Index(['Indvidual\\nin\\nmanuscript', 'g.(hg19) Chr16:',\n",
-       "       'Transcript\\nNM_015133.4\\nc.', 'p.', 'origin', 'genetic testing', 'Sex',\n",
-       "       'age at last assesment', 'prenatal period', 'Exam at birth',\n",
-       "       'body measurements\\n(at last assesment if not otherwise specified)',\n",
-       "       'DD', 'severity of ID', 'development', 'regression', 'autism',\n",
-       "       'hypotonia', 'movement disorder', 'CVI', 'neurological examination',\n",
-       "       'result of external MRI', 'seizures', 'Sz onset and Sz types',\n",
-       "       'AEDs used', 'Sz outcome', 'EEG', 'Additional symptoms',\n",
-       "       'family history', 'further results of genetic testing'],\n",
-       "      dtype='object')"
-      ]
-     },
-     "execution_count": 8,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "df.columns"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "9cad6d50",
-   "metadata": {},
-   "source": [
-    "<h2>Collecting column mappings for the entire table</h2>\n",
-    "<p>pyphetools expects to get a disctionary whose keys correspond to the column names used by the pandas DataFrame, and the values are the corresponding ColumnMapper objects. In the following, we create this dictionary and then, in the following cells, we create a ColumnMapper object for each of the columns to be mapped.</p>"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 9,
-   "id": "241b064e",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "column_mapper_d = defaultdict(ColumnMapper)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "91cb8c28",
-   "metadata": {},
-   "source": [
-    "<h3>Step 2: Encode each column of interest using the ColumnMapper class</h3>\n",
-    "<p>We will show how to work with the ColumnMapper class in detail using the 'neurological examination' column. The basic idea is to make one ColumnMapper object for each column of interest. The column mapper knows how to map the contents using either default exact text matching or custom maps from whatever strings to HPO terms.</p>\n",
-    "<p>The first step is to create a ColumnMapper object and use the preview_column feature to see how many terms can be mapped using exact text mining</p>"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 10,
-   "id": "c375e0d2",
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>column</th>\n",
-       "      <th>terms</th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>0</th>\n",
-       "      <td>ataxia</td>\n",
-       "      <td>Ataxia (HP:0001251)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>1</th>\n",
-       "      <td>NaN</td>\n",
-       "      <td>n/a</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>2</th>\n",
-       "      <td>spastic paraplegia</td>\n",
-       "      <td>Spastic paraplegia (HP:0001258)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>3</th>\n",
-       "      <td>spasticity; nerve conduction and EMG studies with abnormal findings \"remarkable for the failure to activate the leg muscles due to an upper motor neuron pattern of aberrant motor unit potential firing rates. These findings are consistent with dysfunction of the corticospinal pathways rather than a lower motor unit.\" Significant low extremity weakness.</td>\n",
-       "      <td>Spasticity (HP:0001257); Asthenia (HP:0025406)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>4</th>\n",
-       "      <td>spasticity/stiff legs</td>\n",
-       "      <td>Spasticity (HP:0001257)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>5</th>\n",
-       "      <td>spastic diplegic cerebral palsy</td>\n",
-       "      <td>Cerebral palsy (HP:0100021); Spastic diplegia (HP:0001264)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>6</th>\n",
-       "      <td>orobuccal dyspraxia, awkward gross and fine motricity, difficulty in coordination, unstable gait</td>\n",
-       "      <td>n/a</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "                                                                                                                                                                                                                                                                                                                                                              column  \\\n",
-       "0                                                                                                                                                                                                                                                                                                                                                             ataxia   \n",
-       "1                                                                                                                                                                                                                                                                                                                                                                NaN   \n",
-       "2                                                                                                                                                                                                                                                                                                                                                 spastic paraplegia   \n",
-       "3  spasticity; nerve conduction and EMG studies with abnormal findings \"remarkable for the failure to activate the leg muscles due to an upper motor neuron pattern of aberrant motor unit potential firing rates. These findings are consistent with dysfunction of the corticospinal pathways rather than a lower motor unit.\" Significant low extremity weakness.   \n",
-       "4                                                                                                                                                                                                                                                                                                                                              spasticity/stiff legs   \n",
-       "5                                                                                                                                                                                                                                                                                                                                    spastic diplegic cerebral palsy   \n",
-       "6                                                                                                                                                                                                                                                                   orobuccal dyspraxia, awkward gross and fine motricity, difficulty in coordination, unstable gait   \n",
-       "\n",
-       "                                                        terms  \n",
-       "0                                         Ataxia (HP:0001251)  \n",
-       "1                                                         n/a  \n",
-       "2                             Spastic paraplegia (HP:0001258)  \n",
-       "3              Spasticity (HP:0001257); Asthenia (HP:0025406)  \n",
-       "4                                     Spasticity (HP:0001257)  \n",
-       "5  Cerebral palsy (HP:0100021); Spastic diplegia (HP:0001264)  \n",
-       "6                                                         n/a  "
-      ]
-     },
-     "execution_count": 10,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "neuroMapper = CustomColumnMapper(concept_recognizer=hpo_cr)\n",
-    "neuroMapper.preview_column(df['neurological examination'])"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "8908f55e",
-   "metadata": {},
-   "source": [
-    "<h3>Adding manual mappings: CustomColumnMapper</h3>\n",
-    "<p>We can see that the string in the first column, 'ataxia' was mapped to the HPO term <i>Ataxia</i> (HP:0001251), and that several other concepts were identified. However, we missed several concepts that do not match exactly with HPO term labels or synonyms, but can be mapped using some domain knonwledge. For instance, low extremity weakness appears to be equivalent to <i>Lower limb muscle weakness</i> (HP:0007340).</p>\n",
-    "<p>To add these mappings, users should look up the primary label of the HPO terms in question and create a dictionary that maps the phrases used in the supplemental material to the HPO labels. The following cell shows a map for the 'neurological examination' column and calls the ColumnMapper constructor with this custom map</p>"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 8,
-   "id": "6110f1ce",
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>column</th>\n",
-       "      <th>terms</th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>0</th>\n",
-       "      <td>ataxia</td>\n",
-       "      <td>Ataxia (HP:0001251)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>1</th>\n",
-       "      <td>NaN</td>\n",
-       "      <td>n/a</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>2</th>\n",
-       "      <td>spastic paraplegia</td>\n",
-       "      <td>Spastic paraplegia (HP:0001258)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>3</th>\n",
-       "      <td>spasticity; nerve conduction and EMG studies with abnormal findings \"remarkable for the failure to activate the leg muscles due to an upper motor neuron pattern of aberrant motor unit potential firing rates. These findings are consistent with dysfunction of the corticospinal pathways rather than a lower motor unit.\" Significant low extremity weakness.</td>\n",
-       "      <td>Spasticity (HP:0001257); Upper motor neuron dysfunction (HP:0002493); Lower limb muscle weakness (HP:0007340)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>4</th>\n",
-       "      <td>spasticity/stiff legs</td>\n",
-       "      <td>Spasticity (HP:0001257)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>5</th>\n",
-       "      <td>spastic diplegic cerebral palsy</td>\n",
-       "      <td>Cerebral palsy (HP:0100021); Spastic diplegia (HP:0001264)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>6</th>\n",
-       "      <td>orobuccal dyspraxia, awkward gross and fine motricity, difficulty in coordination, unstable gait</td>\n",
-       "      <td>Oromotor apraxia (HP:0007301); Poor coordination (HP:0002370); Unsteady gait (HP:0002317)</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "                                                                                                                                                                                                                                                                                                                                                              column  \\\n",
-       "0                                                                                                                                                                                                                                                                                                                                                             ataxia   \n",
-       "1                                                                                                                                                                                                                                                                                                                                                                NaN   \n",
-       "2                                                                                                                                                                                                                                                                                                                                                 spastic paraplegia   \n",
-       "3  spasticity; nerve conduction and EMG studies with abnormal findings \"remarkable for the failure to activate the leg muscles due to an upper motor neuron pattern of aberrant motor unit potential firing rates. These findings are consistent with dysfunction of the corticospinal pathways rather than a lower motor unit.\" Significant low extremity weakness.   \n",
-       "4                                                                                                                                                                                                                                                                                                                                              spasticity/stiff legs   \n",
-       "5                                                                                                                                                                                                                                                                                                                                    spastic diplegic cerebral palsy   \n",
-       "6                                                                                                                                                                                                                                                                   orobuccal dyspraxia, awkward gross and fine motricity, difficulty in coordination, unstable gait   \n",
-       "\n",
-       "                                                                                                           terms  \n",
-       "0                                                                                            Ataxia (HP:0001251)  \n",
-       "1                                                                                                            n/a  \n",
-       "2                                                                                Spastic paraplegia (HP:0001258)  \n",
-       "3  Spasticity (HP:0001257); Upper motor neuron dysfunction (HP:0002493); Lower limb muscle weakness (HP:0007340)  \n",
-       "4                                                                                        Spasticity (HP:0001257)  \n",
-       "5                                                     Cerebral palsy (HP:0100021); Spastic diplegia (HP:0001264)  \n",
-       "6                      Oromotor apraxia (HP:0007301); Poor coordination (HP:0002370); Unsteady gait (HP:0002317)  "
-      ]
-     },
-     "execution_count": 8,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "neuro_exam_custom_map = {'low extremity weakness': 'Lower limb muscle weakness',  \n",
-    "                         'unstable gait': 'Unsteady gait',\n",
-    "                         'dysfunction of the corticospinal pathways':'Upper motor neuron dysfunction',\n",
-    "                         'spastic': 'Spasticity',\n",
-    "                         'orobuccal dyspraxia': 'Oromotor apraxia',\n",
-    "                         'difficulty in coordination':'Poor coordination'\n",
-    "                        }\n",
-    "neuroMapper = CustomColumnMapper(concept_recognizer=hpo_cr, custom_map_d=neuro_exam_custom_map, )\n",
-    "neuroMapper.preview_column(df['neurological examination'])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 9,
-   "id": "dfe2a51f",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "# Add the mapper to the dictionary, using the label of the column in the Supplemental Table\n",
-    "column_mapper_d['neurological examination'] = neuroMapper"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "20bbba01",
-   "metadata": {},
-   "source": [
-    "<h3>Adding manual mappings: SimpleColumnMapper</h3>\n",
-    "<p>The 'DD' column only contains information about <i>Global developmental delay</i> (HP:0001263). We use\n",
-    "    the SimpleColumnMapper class for columns such as this that contain Yes/No information (and sometimes an indication that the item was not measured or information is not available).</p>"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 10,
-   "id": "fea3aeab",
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0    yes\n",
-       "1    yes\n",
-       "2    yes\n",
-       "3    yes\n",
-       "4    yes\n",
-       "Name: DD, dtype: object"
-      ]
-     },
-     "execution_count": 10,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "df['DD'].head()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 11,
-   "id": "7563f955",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "ddMapper = SimpleColumnMapper(hpo_id='HP:0001263',\n",
-    "    hpo_label='Global developmental delay',\n",
-    "    observed='yes',\n",
-    "    excluded='no')"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 12,
-   "id": "1ca33cbc",
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>term</th>\n",
-       "      <th>status</th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>0</th>\n",
-       "      <td>Global developmental delay (HP:0001263)</td>\n",
-       "      <td>observed</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>1</th>\n",
-       "      <td>Global developmental delay (HP:0001263)</td>\n",
-       "      <td>observed</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>2</th>\n",
-       "      <td>Global developmental delay (HP:0001263)</td>\n",
-       "      <td>observed</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>3</th>\n",
-       "      <td>Global developmental delay (HP:0001263)</td>\n",
-       "      <td>observed</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>4</th>\n",
-       "      <td>Global developmental delay (HP:0001263)</td>\n",
-       "      <td>observed</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>5</th>\n",
-       "      <td>Global developmental delay (HP:0001263)</td>\n",
-       "      <td>observed</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>6</th>\n",
-       "      <td>Global developmental delay (HP:0001263)</td>\n",
-       "      <td>observed</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>7</th>\n",
-       "      <td>Global developmental delay (HP:0001263)</td>\n",
-       "      <td>observed</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>8</th>\n",
-       "      <td>Global developmental delay (HP:0001263)</td>\n",
-       "      <td>observed</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>9</th>\n",
-       "      <td>Global developmental delay (HP:0001263)</td>\n",
-       "      <td>observed</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>10</th>\n",
-       "      <td>Global developmental delay (HP:0001263)</td>\n",
-       "      <td>observed</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>11</th>\n",
-       "      <td>Global developmental delay (HP:0001263)</td>\n",
-       "      <td>observed</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>12</th>\n",
-       "      <td>Global developmental delay (HP:0001263)</td>\n",
-       "      <td>observed</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "                                       term    status\n",
-       "0   Global developmental delay (HP:0001263)  observed\n",
-       "1   Global developmental delay (HP:0001263)  observed\n",
-       "2   Global developmental delay (HP:0001263)  observed\n",
-       "3   Global developmental delay (HP:0001263)  observed\n",
-       "4   Global developmental delay (HP:0001263)  observed\n",
-       "5   Global developmental delay (HP:0001263)  observed\n",
-       "6   Global developmental delay (HP:0001263)  observed\n",
-       "7   Global developmental delay (HP:0001263)  observed\n",
-       "8   Global developmental delay (HP:0001263)  observed\n",
-       "9   Global developmental delay (HP:0001263)  observed\n",
-       "10  Global developmental delay (HP:0001263)  observed\n",
-       "11  Global developmental delay (HP:0001263)  observed\n",
-       "12  Global developmental delay (HP:0001263)  observed"
-      ]
-     },
-     "execution_count": 12,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "ddMapper.preview_column(df['DD'])\n",
-    "# Do not add this here, we will add later -- see below"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "a6c192e4",
-   "metadata": {},
-   "source": [
-    "<h2>Adding multiple SimpleColumnMappers at once</h2>\n",
-    "<p>Many supplemental tables use the same set of symbols to indicate that a feature was observed or excluded for multiple items. pyphetools allows users to ingest all of these columns at once. To do so, users need to create a map whose keys represent the headers used in the column and whose values are an array with the corresponding primary labels and IDs of the HPO term.</p>"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 13,
-   "id": "651bf4cd",
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "We created 7 simple column mappers\n"
-     ]
-    }
-   ],
-   "source": [
-    "items = {\n",
-    "    'regression': [\"Developmental regression\",\"HP:0002376\"],\n",
-    "    'autism': ['Autism', 'HP:0000717'],\n",
-    "    'hypotonia': ['Hypotonia', 'HP:0001252'],\n",
-    "    'movement disorder': ['Abnormality of movement', 'HP:0100022'],\n",
-    "    'CVI': ['Cerebral visual impairment', 'HP:0100704'], # CVI stands for Cortical visual impairment HP:0100704\n",
-    "    'seizures': ['Seizure','HP:0001250'],\n",
-    "    'DD': ['Global developmental delay', 'HP:0001263']\n",
-    "}\n",
-    "item_column_mapper_d = hpo_cr.initialize_simple_column_maps(column_name_to_hpo_label_map=items, observed='yes',\n",
-    "    excluded='no')\n",
-    "print(f\"We created {len(item_column_mapper_d)} simple column mappers\")\n",
-    "# Transfer to column_mapper_d\n",
-    "for k, v in item_column_mapper_d.items():\n",
-    "    column_mapper_d[k] = v"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "a1b0f492",
-   "metadata": {},
-   "source": [
-    "<h3>Adding manual mappings from a list of options: OptionColumnMapper</h3>\n",
-    "<p>In some cases, a columnn has just a few options that may need to be manually mapped. In our example, the column 'severity of ID' contains <i>Intellectual disability, severe</i> (HP:0010864)  <i>Intellectual disability, moderate</i>  (HP:0002342), and <i>Intellectual disability, mild</i> (HP:0001256)</p>\n",
-    "<p>We use the OptionColumnMapper class for such cases.</p>"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 14,
-   "id": "dd484d7a",
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0            moderate\\n(IQ 48)\n",
-       "1                       severe\n",
-       "2                     moderate\n",
-       "3                         mild\n",
-       "4     moderate\\n(IQ 49 and 65)\n",
-       "5                         mild\n",
-       "6                         mild\n",
-       "7                       severe\n",
-       "8                     moderate\n",
-       "9                     moderate\n",
-       "10                    moderate\n",
-       "11                      severe\n",
-       "12           moderate\\n(IQ 49)\n",
-       "Name: severity of ID, dtype: object"
-      ]
-     },
-     "execution_count": 14,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "df['severity of ID']"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 15,
-   "id": "6f25c33d",
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>terms</th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>0</th>\n",
-       "      <td>HP:0002342 (Intellectual disability, moderate/observed); HP:0002342 (Intellectual disability, moderate/observed)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>1</th>\n",
-       "      <td>HP:0010864 (Intellectual disability, severe/observed)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>2</th>\n",
-       "      <td>HP:0002342 (Intellectual disability, moderate/observed)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>3</th>\n",
-       "      <td>HP:0001256 (Intellectual disability, mild/observed)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>4</th>\n",
-       "      <td>HP:0002342 (Intellectual disability, moderate/observed)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>5</th>\n",
-       "      <td>HP:0001256 (Intellectual disability, mild/observed)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>6</th>\n",
-       "      <td>HP:0001256 (Intellectual disability, mild/observed)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>7</th>\n",
-       "      <td>HP:0010864 (Intellectual disability, severe/observed)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>8</th>\n",
-       "      <td>HP:0002342 (Intellectual disability, moderate/observed)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>9</th>\n",
-       "      <td>HP:0002342 (Intellectual disability, moderate/observed)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>10</th>\n",
-       "      <td>HP:0002342 (Intellectual disability, moderate/observed)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>11</th>\n",
-       "      <td>HP:0010864 (Intellectual disability, severe/observed)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>12</th>\n",
-       "      <td>HP:0002342 (Intellectual disability, moderate/observed); HP:0002342 (Intellectual disability, moderate/observed)</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "                                                                                                               terms\n",
-       "0   HP:0002342 (Intellectual disability, moderate/observed); HP:0002342 (Intellectual disability, moderate/observed)\n",
-       "1                                                              HP:0010864 (Intellectual disability, severe/observed)\n",
-       "2                                                            HP:0002342 (Intellectual disability, moderate/observed)\n",
-       "3                                                                HP:0001256 (Intellectual disability, mild/observed)\n",
-       "4                                                            HP:0002342 (Intellectual disability, moderate/observed)\n",
-       "5                                                                HP:0001256 (Intellectual disability, mild/observed)\n",
-       "6                                                                HP:0001256 (Intellectual disability, mild/observed)\n",
-       "7                                                              HP:0010864 (Intellectual disability, severe/observed)\n",
-       "8                                                            HP:0002342 (Intellectual disability, moderate/observed)\n",
-       "9                                                            HP:0002342 (Intellectual disability, moderate/observed)\n",
-       "10                                                           HP:0002342 (Intellectual disability, moderate/observed)\n",
-       "11                                                             HP:0010864 (Intellectual disability, severe/observed)\n",
-       "12  HP:0002342 (Intellectual disability, moderate/observed); HP:0002342 (Intellectual disability, moderate/observed)"
-      ]
-     },
-     "execution_count": 15,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "severity_d = {'moderate\\n(IQ 48)':'Intellectual disability, moderate',\n",
-    "             'moderate':'Intellectual disability, moderate',\n",
-    "             'moderate\\n(IQ 49)': 'Intellectual disability, moderate',\n",
-    "             'severe': 'Intellectual disability, severe',\n",
-    "             'mild': 'Intellectual disability, mild'}\n",
-    "severityOfIdMapper = OptionColumnMapper(concept_recognizer=hpo_cr, option_d=severity_d)\n",
-    "severityOfIdMapper.preview_column(df['severity of ID'])"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "6b1ef151",
-   "metadata": {},
-   "source": [
-    "<h3>The remaining columns</h3>\n",
-    "<p>We now create CustomColumnMappers for the remaining columns with less comments.</p>"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 16,
-   "id": "36d57edb",
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>column</th>\n",
-       "      <th>terms</th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>0</th>\n",
-       "      <td>mild cerebellar atrophy, hypointensity of the globi pallidi and substantia nigra, possible mild degree of abnormal iron or mineral deposition</td>\n",
-       "      <td>Cerebellar atrophy (HP:0001272)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>1</th>\n",
-       "      <td>normal</td>\n",
-       "      <td>n/a</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>2</th>\n",
-       "      <td>Stable areas of T2 hyperintensity involving the central tegmental tracts</td>\n",
-       "      <td>n/a</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>3</th>\n",
-       "      <td>no MRI done</td>\n",
-       "      <td>n/a</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>4</th>\n",
-       "      <td>perisylvian polymicrogyria</td>\n",
-       "      <td>Perisylvian polymicrogyria (HP:0012650)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>5</th>\n",
-       "      <td>perisylvian polymicrogyria extending from the superior/transverse temporal lobes into the frontal opercula</td>\n",
-       "      <td>Perisylvian polymicrogyria (HP:0012650)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>6</th>\n",
-       "      <td>hypomyelination and thin corpus callosum</td>\n",
-       "      <td>CNS hypomyelination (HP:0003429); Thin corpus callosum (HP:0033725)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>7</th>\n",
-       "      <td>severe diffuse thinning of CC and relative hypoplasia of mesencephalon and brainstem, diffusely diminished cerebral white matter, and spinal cord malacia. \\n\\nMost recent brain MRI scan was significant for \"diffusely thin corpus callosum with global cerebral features of white matter volume loss. There is some abnormal FLAIR hyperintensity throughout the cerebral white matter most conspicuous within the periatrial white matter. Thinning of the cerebral white matter tracts is diffuse and not restricted to periventricular or deep white matter fibers and extends to the  subcortical U. fibers resulting in an appearance analogous to polymicrogyria due to close approximation of the cortical mantle. Gray matter lesions are not seen and there appears be sparing of the brainstem and mesencephalon other than probable components of Wallerian degeneration. In summary, there has been progressive myelinization since last exam. The pattern of white matter loss and abnormality including involvement of the subcortical U fibers is atypical raising the question of a concomitant white matter metabolic disorder\"; Spine MRI scan indicates inferior vermian hypoplasia and stable diffuse cord thinning. No focal cord lesion, syrinx or abnormal signal intensity. Findings appear stable from prior.</td>\n",
-       "      <td>Hypoplasia of the brainstem (HP:0002365); Thin corpus callosum (HP:0033725); Reduced cerebral white matter volume (HP:0034295); Polymicrogyria (HP:0002126); Thin corpus callosum (HP:0033725); Pica (HP:0011856); Reduced cerebral white matter volume (HP:0034295); Syringomyelia (HP:0003396)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>8</th>\n",
-       "      <td>widened lateral ventricles and thin corpus callosum</td>\n",
-       "      <td>Lateral ventricle dilatation (HP:0006956); Thin corpus callosum (HP:0033725)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>9</th>\n",
-       "      <td>periventricular leukomalacia, dysgenesis of corpus callosum</td>\n",
-       "      <td>Periventricular leukomalacia (HP:0006970); Dysplastic corpus callosum (HP:0006989)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>10</th>\n",
-       "      <td>Enlargement of the posterior portion of the lateral ventricles, thinning of the posterior third of the corpus callosum; reduced thickness of the posterior bihemispheric white matter</td>\n",
-       "      <td>n/a</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       column  \\\n",
-       "0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               mild cerebellar atrophy, hypointensity of the globi pallidi and substantia nigra, possible mild degree of abnormal iron or mineral deposition   \n",
-       "1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      normal   \n",
-       "2                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Stable areas of T2 hyperintensity involving the central tegmental tracts   \n",
-       "3                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 no MRI done   \n",
-       "4                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  perisylvian polymicrogyria   \n",
-       "5                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  perisylvian polymicrogyria extending from the superior/transverse temporal lobes into the frontal opercula   \n",
-       "6                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    hypomyelination and thin corpus callosum   \n",
-       "7   severe diffuse thinning of CC and relative hypoplasia of mesencephalon and brainstem, diffusely diminished cerebral white matter, and spinal cord malacia. \\n\\nMost recent brain MRI scan was significant for \"diffusely thin corpus callosum with global cerebral features of white matter volume loss. There is some abnormal FLAIR hyperintensity throughout the cerebral white matter most conspicuous within the periatrial white matter. Thinning of the cerebral white matter tracts is diffuse and not restricted to periventricular or deep white matter fibers and extends to the  subcortical U. fibers resulting in an appearance analogous to polymicrogyria due to close approximation of the cortical mantle. Gray matter lesions are not seen and there appears be sparing of the brainstem and mesencephalon other than probable components of Wallerian degeneration. In summary, there has been progressive myelinization since last exam. The pattern of white matter loss and abnormality including involvement of the subcortical U fibers is atypical raising the question of a concomitant white matter metabolic disorder\"; Spine MRI scan indicates inferior vermian hypoplasia and stable diffuse cord thinning. No focal cord lesion, syrinx or abnormal signal intensity. Findings appear stable from prior.   \n",
-       "8                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         widened lateral ventricles and thin corpus callosum   \n",
-       "9                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 periventricular leukomalacia, dysgenesis of corpus callosum   \n",
-       "10                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Enlargement of the posterior portion of the lateral ventricles, thinning of the posterior third of the corpus callosum; reduced thickness of the posterior bihemispheric white matter   \n",
-       "\n",
-       "                                                                                                                                                                                                                                                                                               terms  \n",
-       "0                                                                                                                                                                                                                                                                    Cerebellar atrophy (HP:0001272)  \n",
-       "1                                                                                                                                                                                                                                                                                                n/a  \n",
-       "2                                                                                                                                                                                                                                                                                                n/a  \n",
-       "3                                                                                                                                                                                                                                                                                                n/a  \n",
-       "4                                                                                                                                                                                                                                                            Perisylvian polymicrogyria (HP:0012650)  \n",
-       "5                                                                                                                                                                                                                                                            Perisylvian polymicrogyria (HP:0012650)  \n",
-       "6                                                                                                                                                                                                                                CNS hypomyelination (HP:0003429); Thin corpus callosum (HP:0033725)  \n",
-       "7   Hypoplasia of the brainstem (HP:0002365); Thin corpus callosum (HP:0033725); Reduced cerebral white matter volume (HP:0034295); Polymicrogyria (HP:0002126); Thin corpus callosum (HP:0033725); Pica (HP:0011856); Reduced cerebral white matter volume (HP:0034295); Syringomyelia (HP:0003396)  \n",
-       "8                                                                                                                                                                                                                       Lateral ventricle dilatation (HP:0006956); Thin corpus callosum (HP:0033725)  \n",
-       "9                                                                                                                                                                                                                 Periventricular leukomalacia (HP:0006970); Dysplastic corpus callosum (HP:0006989)  \n",
-       "10                                                                                                                                                                                                                                                                                               n/a  "
-      ]
-     },
-     "execution_count": 16,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "mri_custom_map = {'hypomyelination': 'CNS hypomyelination',  \n",
-    "                  'thinning of CC': 'Thin corpus callosum',\n",
-    "                  'white matter volume loss':'Reduced cerebral white matter volume',\n",
-    "                  'widened lateral ventricles': 'Lateral ventricle dilatation',\n",
-    "                  'dysgenesis of corpus callosum': 'Dysplastic corpus callosum',\n",
-    "                  'hypoplasia of mesencephalon and brainstem': 'Hypoplasia of the brainstem'\n",
-    "                  }\n",
-    "mriMapper = CustomColumnMapper(concept_recognizer=hpo_cr, custom_map_d=mri_custom_map, )\n",
-    "mriMapper.preview_column(df['result of external MRI'])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 17,
-   "id": "161c8034",
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>column</th>\n",
-       "      <th>terms</th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>0</th>\n",
-       "      <td>speech is ataxic but speaks in sentences/short phrases; attention issues, impulse control and emotional lability, OCD symptoms; recently developed scoliosis</td>\n",
-       "      <td>Emotional lability (HP:0000712); Scoliosis (HP:0002650)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>1</th>\n",
-       "      <td>pre-natal pelvi-ureteric junction stenosis (spontaneous resolution at 6 m)</td>\n",
-       "      <td>n/a</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>2</th>\n",
-       "      <td>Nystagmus</td>\n",
-       "      <td>Nystagmus (HP:0000639)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>3</th>\n",
-       "      <td>Left hearing loss; Dysmorphic features: hypertelorism inner canthal distance 4.3cm; low set prominent ears, slight overhangin columella, hypodontia; 5th finger clinodactyly and 5th finger brachydactylky; synophrys; Encopresis</td>\n",
-       "      <td>Hearing impairment (HP:0000365); Hypertelorism (HP:0000316); Protruding ear (HP:0000411); Hypodontia (HP:0000668); Finger clinodactyly (HP:0040019); Synophrys (HP:0000664); Encopresis (HP:0040183)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>4</th>\n",
-       "      <td>no dysmorphism, small teeth, severe s-configured scoliosis of thoracic and lumbar spine</td>\n",
-       "      <td>Microdontia (HP:0000691); Scoliosis (HP:0002650)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>5</th>\n",
-       "      <td>NaN</td>\n",
-       "      <td>n/a</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>6</th>\n",
-       "      <td>full cheeks, long philtrum, slight micrognatia, no specific dysmorphic features</td>\n",
-       "      <td>Full cheeks (HP:0000293); Long philtrum (HP:0000343)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>7</th>\n",
-       "      <td>normal birth weight, dramatic increased weight without excessive calorie intake; Small hands and feet.</td>\n",
-       "      <td>Small hand (HP:0200055)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>8</th>\n",
-       "      <td>no dysmorphism</td>\n",
-       "      <td>n/a</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>9</th>\n",
-       "      <td>behavior: biting, scratching, throwing if fustrated, but generally happy dispositiion; myopic astigmatism and pseudostrabismus</td>\n",
-       "      <td>Strabismus (HP:0000486); Myopic astigmatism (HP:0500041)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>10</th>\n",
-       "      <td>Gastroesophageal reflux, macroprolactinemia, steatosic hepatomegaly. Dysmorphisms: thin/long face, short forehead, thick eyebrows, dee-pset eyes, narrow palpebral fissures, strabismus, high nasal bridge, anteverted nostrils, short philtrum, small mouth, high palate,  large teeth; truncal obesity, thin fingers, kyphosis, lordosis, scoliosis, bilateral genu valgum, flat-valgus feet</td>\n",
-       "      <td>Gastroesophageal reflux (HP:0002020); Hepatomegaly (HP:0002240); Long face (HP:0000276); Thick eyebrow (HP:0000574); Narrow palpebral fissure (HP:0045025); Strabismus (HP:0000486); Prominent nasal bridge (HP:0000426); Anteverted nares (HP:0000463); Short philtrum (HP:0000322); Narrow mouth (HP:0000160); High palate (HP:0000218); Truncal obesity (HP:0001956); Slender finger (HP:0001238); Kyphosis (HP:0002808); Hyperlordosis (HP:0003307); Scoliosis (HP:0002650); Genu valgum (HP:0002857)</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "                                                                                                                                                                                                                                                                                                                                                                                            column  \\\n",
-       "0                                                                                                                                                                                                                                     speech is ataxic but speaks in sentences/short phrases; attention issues, impulse control and emotional lability, OCD symptoms; recently developed scoliosis   \n",
-       "1                                                                                                                                                                                                                                                                                                                       pre-natal pelvi-ureteric junction stenosis (spontaneous resolution at 6 m)   \n",
-       "2                                                                                                                                                                                                                                                                                                                                                                                        Nystagmus   \n",
-       "3                                                                                                                                                                Left hearing loss; Dysmorphic features: hypertelorism inner canthal distance 4.3cm; low set prominent ears, slight overhangin columella, hypodontia; 5th finger clinodactyly and 5th finger brachydactylky; synophrys; Encopresis   \n",
-       "4                                                                                                                                                                                                                                                                                                          no dysmorphism, small teeth, severe s-configured scoliosis of thoracic and lumbar spine   \n",
-       "5                                                                                                                                                                                                                                                                                                                                                                                              NaN   \n",
-       "6                                                                                                                                                                                                                                                                                                                  full cheeks, long philtrum, slight micrognatia, no specific dysmorphic features   \n",
-       "7                                                                                                                                                                                                                                                                                           normal birth weight, dramatic increased weight without excessive calorie intake; Small hands and feet.   \n",
-       "8                                                                                                                                                                                                                                                                                                                                                                                   no dysmorphism   \n",
-       "9                                                                                                                                                                                                                                                                   behavior: biting, scratching, throwing if fustrated, but generally happy dispositiion; myopic astigmatism and pseudostrabismus   \n",
-       "10  Gastroesophageal reflux, macroprolactinemia, steatosic hepatomegaly. Dysmorphisms: thin/long face, short forehead, thick eyebrows, dee-pset eyes, narrow palpebral fissures, strabismus, high nasal bridge, anteverted nostrils, short philtrum, small mouth, high palate,  large teeth; truncal obesity, thin fingers, kyphosis, lordosis, scoliosis, bilateral genu valgum, flat-valgus feet   \n",
-       "\n",
-       "                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        terms  \n",
-       "0                                                                                                                                                                                                                                                                                                                                                                                                                                                     Emotional lability (HP:0000712); Scoliosis (HP:0002650)  \n",
-       "1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         n/a  \n",
-       "2                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Nystagmus (HP:0000639)  \n",
-       "3                                                                                                                                                                                                                                                                                                        Hearing impairment (HP:0000365); Hypertelorism (HP:0000316); Protruding ear (HP:0000411); Hypodontia (HP:0000668); Finger clinodactyly (HP:0040019); Synophrys (HP:0000664); Encopresis (HP:0040183)  \n",
-       "4                                                                                                                                                                                                                                                                                                                                                                                                                                                            Microdontia (HP:0000691); Scoliosis (HP:0002650)  \n",
-       "5                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         n/a  \n",
-       "6                                                                                                                                                                                                                                                                                                                                                                                                                                                        Full cheeks (HP:0000293); Long philtrum (HP:0000343)  \n",
-       "7                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     Small hand (HP:0200055)  \n",
-       "8                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         n/a  \n",
-       "9                                                                                                                                                                                                                                                                                                                                                                                                                                                    Strabismus (HP:0000486); Myopic astigmatism (HP:0500041)  \n",
-       "10  Gastroesophageal reflux (HP:0002020); Hepatomegaly (HP:0002240); Long face (HP:0000276); Thick eyebrow (HP:0000574); Narrow palpebral fissure (HP:0045025); Strabismus (HP:0000486); Prominent nasal bridge (HP:0000426); Anteverted nares (HP:0000463); Short philtrum (HP:0000322); Narrow mouth (HP:0000160); High palate (HP:0000218); Truncal obesity (HP:0001956); Slender finger (HP:0001238); Kyphosis (HP:0002808); Hyperlordosis (HP:0003307); Scoliosis (HP:0002650); Genu valgum (HP:0002857)  "
-      ]
-     },
-     "execution_count": 17,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "additional_custom_map = {'OCD': 'Obsessive-compulsive behavior',  \n",
-    "                         '5th finger clinodactyly': 'Clinodactyly of the 5th finger',\n",
-    "                         'small teeth':'Reduced cerebral white matter volume',\n",
-    "                         'widened lateral ventricles': 'Lateral ventricle dilatation',\n",
-    "                         'dysgenesis of corpus callosum': 'Dysplastic corpus callosum',\n",
-    "                         'dramatic increased weight': 'Obesity'\n",
-    "                        }\n",
-    "excluded = {'pseudostrabismus'}\n",
-    "additionalFeaturesMapper = CustomColumnMapper(concept_recognizer=hpo_cr, \n",
-    "                                              custom_map_d=mri_custom_map, \n",
-    "                                              excluded_set=excluded)\n",
-    "mriMapper.preview_column(df['Additional symptoms'])"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "94494556",
-   "metadata": {},
-   "source": [
-    "<H1>Mapping variants</H1>\n",
-    "<p>pyphetools maps variants using the VariantValidator API.</p>"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 18,
-   "id": "289d507d",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "genome = 'hg38'\n",
-    "transcript='NM_015133.4'\n",
-    "varMapper = VariantColumnMapper(assembly=genome,\n",
-    "                                column_name='Transcript\\nNM_015133.4\\nc.', \n",
-    "                                transcript=transcript, \n",
-    "                                default_genotype='heterozygous')"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "c8de6940",
-   "metadata": {},
-   "source": [
-    "<p>To use this tool, identify the column that contains valid HGVS nomenclature for the variants. Also, if there is a genotype (\"heterozygous\", \"homozygous\", \"hemizygous\") that applies to all variants, it can be used here.</p>\n",
-    "<p>This is the easiest situation (For instance, if each individual in the cohort has one heterozygous variant, we can specify this using the <tt>default_genotype</tt> argument).</p>"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 19,
-   "id": "e8e35a7f",
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "0        c.65delG\n",
-       "1         c.79G>T\n",
-       "2        c.111C>G\n",
-       "3     c.1198G>A  \n",
-       "4       c.1331T>C\n",
-       "5       c.1331T>C\n",
-       "6       c.1574G>A\n",
-       "7       c.1732C>T\n",
-       "8       c.1732C>T\n",
-       "9       c.2982C>G\n",
-       "10      c.3436C>T\n",
-       "11      c.3436C>T\n",
-       "12      c.3436C>T\n",
-       "Name: Transcript\\nNM_015133.4\\nc., dtype: object"
-      ]
-     },
-     "execution_count": 19,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "df['Transcript\\nNM_015133.4\\nc.']"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 20,
-   "id": "a0508264",
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.65delG/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.79G>T/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.111C>G/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.1198G>A  /NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.1331T>C/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.1331T>C/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.1574G>A/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.1732C>T/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.1732C>T/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.2982C>G/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.3436C>T/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.3436C>T/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.3436C>T/NM_015133.4?content-type=application%2Fjson\n"
-     ]
-    },
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>variant</th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>0</th>\n",
-       "      <td>NM_015133.4:c.65del</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>1</th>\n",
-       "      <td>NM_015133.4:c.79G&gt;T</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>2</th>\n",
-       "      <td>NM_015133.4:c.111C&gt;G</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>3</th>\n",
-       "      <td>NM_015133.4:c.1198G&gt;A</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>4</th>\n",
-       "      <td>NM_015133.4:c.1331T&gt;C</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>5</th>\n",
-       "      <td>NM_015133.4:c.1331T&gt;C</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>6</th>\n",
-       "      <td>NM_015133.4:c.1574G&gt;A</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>7</th>\n",
-       "      <td>NM_015133.4:c.1732C&gt;T</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>8</th>\n",
-       "      <td>NM_015133.4:c.1732C&gt;T</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>9</th>\n",
-       "      <td>NM_015133.4:c.2982C&gt;G</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>10</th>\n",
-       "      <td>NM_015133.4:c.3436C&gt;T</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>11</th>\n",
-       "      <td>NM_015133.4:c.3436C&gt;T</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>12</th>\n",
-       "      <td>NM_015133.4:c.3436C&gt;T</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "                  variant\n",
-       "0     NM_015133.4:c.65del\n",
-       "1     NM_015133.4:c.79G>T\n",
-       "2    NM_015133.4:c.111C>G\n",
-       "3   NM_015133.4:c.1198G>A\n",
-       "4   NM_015133.4:c.1331T>C\n",
-       "5   NM_015133.4:c.1331T>C\n",
-       "6   NM_015133.4:c.1574G>A\n",
-       "7   NM_015133.4:c.1732C>T\n",
-       "8   NM_015133.4:c.1732C>T\n",
-       "9   NM_015133.4:c.2982C>G\n",
-       "10  NM_015133.4:c.3436C>T\n",
-       "11  NM_015133.4:c.3436C>T\n",
-       "12  NM_015133.4:c.3436C>T"
-      ]
-     },
-     "execution_count": 20,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "varMapper.preview_column(df['Transcript\\nNM_015133.4\\nc.'])"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "97e1dae7",
-   "metadata": {},
-   "source": [
-    "<h1>Putting it all together</h1>\n",
-    "<p>We now parse the entire DataFrame to generate lists of terms for each patient. We additionally need to specify the columns that contain age and sex and patient ids. We also include the PMID of the published article, which we will use for the output file names.</p>"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 21,
-   "id": "5a2c7964",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "ageMapper = AgeColumnMapper.by_year_and_month('age at last assesment')\n",
-    "ageMapper.preview_column(df['age at last assesment'])\n",
-    "\n",
-    "sexMapper = SexColumnMapper(male_symbol='M', female_symbol='F', column_name='Sex')\n",
-    "sexMapper.preview_column(df['Sex'])\n",
-    "\n",
-    "individual_column_name = 'Indvidual\\nin\\nmanuscript'\n",
-    "\n",
-    "pmid = \"PMID:30612693\"\n",
-    "encoder = CohortEncoder(df=df, hpo_cr=hpo_cr, column_mapper_d=column_mapper_d, \n",
-    "                        individual_column_name=individual_column_name,\n",
-    "                        agemapper=ageMapper, sexmapper=sexMapper,\n",
-    "                        variant_mapper=varMapper,metadata=metadata,pmid=pmid)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "d661739e",
-   "metadata": {},
-   "source": [
-    "<H2>Specifying the disease</H2>\n",
-    "<p>The disease is specified as a CURIE (disease id, e.g., <tt>OMIM:154700</tt>) and label, e.g., <tt>Marfan syndrome</tt>. The following function assumes that all individuals in the Supplemental file have the same disease, and so we set the disease for the entire cohort encoder.</p>"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 22,
-   "id": "b32fe772",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "disease_id = 'OMIM:618443'\n",
-    "disease_name = 'Neurodevelopmental disorder with or without variable brain abnormalities'\n",
-    "\n",
-    "encoder.set_disease(disease_id=disease_id, label=disease_name)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "5f3e2968",
-   "metadata": {},
-   "source": [
-    "<h2>Preview</h2>\n",
-    "<p>A preview function is provided to check results before exporting in Phenopacket Schema format.</p>"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 23,
-   "id": "46b5edb1",
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>sex</th>\n",
-       "      <th>age</th>\n",
-       "      <th>phenotypic features</th>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>id</th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>1</th>\n",
-       "      <td>MALE</td>\n",
-       "      <td>P14Y8M</td>\n",
-       "      <td>Ataxia (HP:0001251)\\nexcluded: Developmental regression (HP:0002376)\\nAutism (HP:0000717)\\nHypotonia (HP:0001252)\\nexcluded: Abnormality of movement (HP:0100022)\\nexcluded: Cerebral visual impairment (HP:0100704)\\nexcluded: Seizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>2</th>\n",
-       "      <td>MALE</td>\n",
-       "      <td>P4Y</td>\n",
-       "      <td>Ataxia (HP:0001251)\\nexcluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nHypotonia (HP:0001252)\\nexcluded: Abnormality of movement (HP:0100022)\\nexcluded: Cerebral visual impairment (HP:0100704)\\nexcluded: Seizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>3</th>\n",
-       "      <td>MALE</td>\n",
-       "      <td>P4Y</td>\n",
-       "      <td>excluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nHypotonia (HP:0001252)\\nexcluded: Abnormality of movement (HP:0100022)\\nexcluded: Cerebral visual impairment (HP:0100704)\\nexcluded: Seizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>4</th>\n",
-       "      <td>MALE</td>\n",
-       "      <td>P7Y6M</td>\n",
-       "      <td>excluded: Developmental regression (HP:0002376)\\nAutism (HP:0000717)\\nexcluded: Hypotonia (HP:0001252)\\nexcluded: Abnormality of movement (HP:0100022)\\nexcluded: Cerebral visual impairment (HP:0100704)\\nexcluded: Seizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>5</th>\n",
-       "      <td>MALE</td>\n",
-       "      <td>P10Y</td>\n",
-       "      <td>excluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nHypotonia (HP:0001252)\\nexcluded: Abnormality of movement (HP:0100022)\\nnot measured: Cerebral visual impairment (HP:0100704)\\nSeizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>6</th>\n",
-       "      <td>FEMALE</td>\n",
-       "      <td>P9Y</td>\n",
-       "      <td>excluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nHypotonia (HP:0001252)\\nnot measured: Abnormality of movement (HP:0100022)\\nnot measured: Cerebral visual impairment (HP:0100704)\\nexcluded: Seizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>7</th>\n",
-       "      <td>FEMALE</td>\n",
-       "      <td>P3Y</td>\n",
-       "      <td>excluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nexcluded: Hypotonia (HP:0001252)\\nnot measured: Abnormality of movement (HP:0100022)\\nnot measured: Cerebral visual impairment (HP:0100704)\\nexcluded: Seizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>8</th>\n",
-       "      <td>FEMALE</td>\n",
-       "      <td>P5Y</td>\n",
-       "      <td>Spastic paraplegia (HP:0001258)\\nexcluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nHypotonia (HP:0001252)\\nnot measured: Abnormality of movement (HP:0100022)\\nnot measured: Cerebral visual impairment (HP:0100704)\\nSeizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>9</th>\n",
-       "      <td>FEMALE</td>\n",
-       "      <td>P6Y</td>\n",
-       "      <td>Spasticity (HP:0001257)\\nUpper motor neuron dysfunction (HP:0002493)\\nLower limb muscle weakness (HP:0007340)\\nexcluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nHypotonia (HP:0001252)\\nnot measured: Abnormality of movement (HP:0100022)\\nnot measured: Cerebral visual impairment (HP:0100704)\\nSeizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>10</th>\n",
-       "      <td>MALE</td>\n",
-       "      <td>P4Y</td>\n",
-       "      <td>excluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nHypotonia (HP:0001252)\\nnot measured: Abnormality of movement (HP:0100022)\\nnot measured: Cerebral visual impairment (HP:0100704)\\nSeizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>11</th>\n",
-       "      <td>FEMALE</td>\n",
-       "      <td>P11Y</td>\n",
-       "      <td>Spasticity (HP:0001257)\\nnot measured: Developmental regression (HP:0002376)\\nnot measured: Autism (HP:0000717)\\nexcluded: Hypotonia (HP:0001252)\\nexcluded: Abnormality of movement (HP:0100022)\\nCerebral visual impairment (HP:0100704)\\nexcluded: Seizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>12</th>\n",
-       "      <td>FEMALE</td>\n",
-       "      <td>P4Y6M</td>\n",
-       "      <td>Cerebral palsy (HP:0100021)\\nSpastic diplegia (HP:0001264)\\nexcluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nexcluded: Hypotonia (HP:0001252)\\nnot measured: Abnormality of movement (HP:0100022)\\nexcluded: Cerebral visual impairment (HP:0100704)\\nexcluded: Seizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>13</th>\n",
-       "      <td>FEMALE</td>\n",
-       "      <td>P19Y</td>\n",
-       "      <td>Oromotor apraxia (HP:0007301)\\nPoor coordination (HP:0002370)\\nUnsteady gait (HP:0002317)\\nexcluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nHypotonia (HP:0001252)\\nexcluded: Abnormality of movement (HP:0100022)\\nCerebral visual impairment (HP:0100704)\\nexcluded: Seizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "       sex     age  \\\n",
-       "id                   \n",
-       "1     MALE  P14Y8M   \n",
-       "2     MALE     P4Y   \n",
-       "3     MALE     P4Y   \n",
-       "4     MALE   P7Y6M   \n",
-       "5     MALE    P10Y   \n",
-       "6   FEMALE     P9Y   \n",
-       "7   FEMALE     P3Y   \n",
-       "8   FEMALE     P5Y   \n",
-       "9   FEMALE     P6Y   \n",
-       "10    MALE     P4Y   \n",
-       "11  FEMALE    P11Y   \n",
-       "12  FEMALE   P4Y6M   \n",
-       "13  FEMALE    P19Y   \n",
-       "\n",
-       "                                                                                                                                                                                                                                                                                                                                                                                phenotypic features  \n",
-       "id                                                                                                                                                                                                                                                                                                                                                                                                   \n",
-       "1                                                                                                     Ataxia (HP:0001251)\\nexcluded: Developmental regression (HP:0002376)\\nAutism (HP:0000717)\\nHypotonia (HP:0001252)\\nexcluded: Abnormality of movement (HP:0100022)\\nexcluded: Cerebral visual impairment (HP:0100704)\\nexcluded: Seizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)  \n",
-       "2                                                                                           Ataxia (HP:0001251)\\nexcluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nHypotonia (HP:0001252)\\nexcluded: Abnormality of movement (HP:0100022)\\nexcluded: Cerebral visual impairment (HP:0100704)\\nexcluded: Seizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)  \n",
-       "3                                                                                                                excluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nHypotonia (HP:0001252)\\nexcluded: Abnormality of movement (HP:0100022)\\nexcluded: Cerebral visual impairment (HP:0100704)\\nexcluded: Seizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)  \n",
-       "4                                                                                                                excluded: Developmental regression (HP:0002376)\\nAutism (HP:0000717)\\nexcluded: Hypotonia (HP:0001252)\\nexcluded: Abnormality of movement (HP:0100022)\\nexcluded: Cerebral visual impairment (HP:0100704)\\nexcluded: Seizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)  \n",
-       "5                                                                                                                      excluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nHypotonia (HP:0001252)\\nexcluded: Abnormality of movement (HP:0100022)\\nnot measured: Cerebral visual impairment (HP:0100704)\\nSeizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)  \n",
-       "6                                                                                                        excluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nHypotonia (HP:0001252)\\nnot measured: Abnormality of movement (HP:0100022)\\nnot measured: Cerebral visual impairment (HP:0100704)\\nexcluded: Seizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)  \n",
-       "7                                                                                              excluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nexcluded: Hypotonia (HP:0001252)\\nnot measured: Abnormality of movement (HP:0100022)\\nnot measured: Cerebral visual impairment (HP:0100704)\\nexcluded: Seizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)  \n",
-       "8                                                                                 Spastic paraplegia (HP:0001258)\\nexcluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nHypotonia (HP:0001252)\\nnot measured: Abnormality of movement (HP:0100022)\\nnot measured: Cerebral visual impairment (HP:0100704)\\nSeizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)  \n",
-       "9   Spasticity (HP:0001257)\\nUpper motor neuron dysfunction (HP:0002493)\\nLower limb muscle weakness (HP:0007340)\\nexcluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nHypotonia (HP:0001252)\\nnot measured: Abnormality of movement (HP:0100022)\\nnot measured: Cerebral visual impairment (HP:0100704)\\nSeizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)  \n",
-       "10                                                                                                                 excluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nHypotonia (HP:0001252)\\nnot measured: Abnormality of movement (HP:0100022)\\nnot measured: Cerebral visual impairment (HP:0100704)\\nSeizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)  \n",
-       "11                                                                              Spasticity (HP:0001257)\\nnot measured: Developmental regression (HP:0002376)\\nnot measured: Autism (HP:0000717)\\nexcluded: Hypotonia (HP:0001252)\\nexcluded: Abnormality of movement (HP:0100022)\\nCerebral visual impairment (HP:0100704)\\nexcluded: Seizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)  \n",
-       "12                                     Cerebral palsy (HP:0100021)\\nSpastic diplegia (HP:0001264)\\nexcluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nexcluded: Hypotonia (HP:0001252)\\nnot measured: Abnormality of movement (HP:0100022)\\nexcluded: Cerebral visual impairment (HP:0100704)\\nexcluded: Seizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)  \n",
-       "13                              Oromotor apraxia (HP:0007301)\\nPoor coordination (HP:0002370)\\nUnsteady gait (HP:0002317)\\nexcluded: Developmental regression (HP:0002376)\\nexcluded: Autism (HP:0000717)\\nHypotonia (HP:0001252)\\nexcluded: Abnormality of movement (HP:0100022)\\nCerebral visual impairment (HP:0100704)\\nexcluded: Seizure (HP:0001250)\\nGlobal developmental delay (HP:0001263)  "
-      ]
-     },
-     "execution_count": 23,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "encoder.preview_dataframe()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "6ad7bddc",
-   "metadata": {},
-   "source": [
-    "<h1>Exporting in GA4GH Phenopacket format</h1>\n",
-    "<p>The conversion code is in the Individual class. TODO -- we need to add additional information, mainly the MetaData</p>"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 24,
-   "id": "5182cbb2",
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.65delG/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.79G>T/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.111C>G/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.1198G>A  /NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.1331T>C/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.1331T>C/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.1574G>A/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.1732C>T/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.1732C>T/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.2982C>G/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.3436C>T/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.3436C>T/NM_015133.4?content-type=application%2Fjson\n",
-      "https://rest.variantvalidator.org/VariantValidator/variantvalidator/hg38/NM_015133.4%3Ac.3436C>T/NM_015133.4?content-type=application%2Fjson\n"
-     ]
-    }
-   ],
-   "source": [
-    "individuals = encoder.get_individuals()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 25,
-   "id": "504c86d9",
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "We extracted 13 individuals\n"
-     ]
-    }
-   ],
-   "source": [
-    "print(f\"We extracted {len(individuals)} individuals\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 26,
-   "id": "522ae293",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "i1 = individuals[0]"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 27,
-   "id": "4dffafc8",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "phenopacket1 = i1.to_ga4gh_phenopacket(metadata=metadata.to_ga4gh())"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 28,
-   "id": "eb303667",
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "{\n",
-      "  \"id\": \"1\",\n",
-      "  \"subject\": {\n",
-      "    \"id\": \"1\",\n",
-      "    \"timeAtLastEncounter\": {\n",
-      "      \"age\": {\n",
-      "        \"iso8601duration\": \"P14Y8M\"\n",
-      "      }\n",
-      "    },\n",
-      "    \"sex\": \"MALE\"\n",
-      "  },\n",
-      "  \"phenotypicFeatures\": [\n",
-      "    {\n",
-      "      \"type\": {\n",
-      "        \"id\": \"HP:0001251\",\n",
-      "        \"label\": \"Ataxia\"\n",
-      "      }\n",
-      "    },\n",
-      "    {\n",
-      "      \"type\": {\n",
-      "        \"id\": \"HP:0002376\",\n",
-      "        \"label\": \"Developmental regression\"\n",
-      "      },\n",
-      "      \"excluded\": true\n",
-      "    },\n",
-      "    {\n",
-      "      \"type\": {\n",
-      "        \"id\": \"HP:0000717\",\n",
-      "        \"label\": \"Autism\"\n",
-      "      }\n",
-      "    },\n",
-      "    {\n",
-      "      \"type\": {\n",
-      "        \"id\": \"HP:0001252\",\n",
-      "        \"label\": \"Hypotonia\"\n",
-      "      }\n",
-      "    },\n",
-      "    {\n",
-      "      \"type\": {\n",
-      "        \"id\": \"HP:0100022\",\n",
-      "        \"label\": \"Abnormality of movement\"\n",
-      "      },\n",
-      "      \"excluded\": true\n",
-      "    },\n",
-      "    {\n",
-      "      \"type\": {\n",
-      "        \"id\": \"HP:0100704\",\n",
-      "        \"label\": \"Cerebral visual impairment\"\n",
-      "      },\n",
-      "      \"excluded\": true\n",
-      "    },\n",
-      "    {\n",
-      "      \"type\": {\n",
-      "        \"id\": \"HP:0001250\",\n",
-      "        \"label\": \"Seizure\"\n",
-      "      },\n",
-      "      \"excluded\": true\n",
-      "    },\n",
-      "    {\n",
-      "      \"type\": {\n",
-      "        \"id\": \"HP:0001263\",\n",
-      "        \"label\": \"Global developmental delay\"\n",
-      "      }\n",
-      "    }\n",
-      "  ],\n",
-      "  \"interpretations\": [\n",
-      "    {\n",
-      "      \"id\": \"1\",\n",
-      "      \"progressStatus\": \"SOLVED\",\n",
-      "      \"diagnosis\": {\n",
-      "        \"disease\": {\n",
-      "          \"id\": \"OMIM:618443\",\n",
-      "          \"label\": \"Neurodevelopmental disorder with or without variable brain abnormalities\"\n",
-      "        },\n",
-      "        \"genomicInterpretations\": [\n",
-      "          {\n",
-      "            \"subjectOrBiosampleId\": \"1\",\n",
-      "            \"interpretationStatus\": \"CAUSATIVE\",\n",
-      "            \"variantInterpretation\": {\n",
-      "              \"variationDescriptor\": {\n",
-      "                \"id\": \"var_djFUYjkwuDERKOwQoLWHTdoUl\",\n",
-      "                \"geneContext\": {\n",
-      "                  \"valueId\": \"HGNC:6884\",\n",
-      "                  \"symbol\": \"MAPK8IP3\"\n",
-      "                },\n",
-      "                \"expressions\": [\n",
-      "                  {\n",
-      "                    \"syntax\": \"hgvs.c\",\n",
-      "                    \"value\": \"NM_015133.4:c.65del\"\n",
-      "                  },\n",
-      "                  {\n",
-      "                    \"syntax\": \"hgvs.g\",\n",
-      "                    \"value\": \"NC_000016.10:g.1706404del\"\n",
-      "                  }\n",
-      "                ],\n",
-      "                \"vcfRecord\": {\n",
-      "                  \"genomeAssembly\": \"hg38\",\n",
-      "                  \"chrom\": \"chr16\",\n",
-      "                  \"pos\": \"1706402\",\n",
-      "                  \"ref\": \"CG\",\n",
-      "                  \"alt\": \"C\"\n",
-      "                },\n",
-      "                \"moleculeContext\": \"genomic\",\n",
-      "                \"allelicState\": {\n",
-      "                  \"id\": \"GENO:0000135\",\n",
-      "                  \"label\": \"heterozygous\"\n",
-      "                }\n",
-      "              }\n",
-      "            }\n",
-      "          }\n",
-      "        ]\n",
-      "      }\n",
-      "    }\n",
-      "  ],\n",
-      "  \"metaData\": {\n",
-      "    \"created\": \"2023-08-28T08:07:09.997185945Z\",\n",
-      "    \"createdBy\": \"ORCID:0000-0002-0736-9199\",\n",
-      "    \"resources\": [\n",
-      "      {\n",
-      "        \"id\": \"geno\",\n",
-      "        \"name\": \"Genotype Ontology\",\n",
-      "        \"url\": \"http://purl.obolibrary.org/obo/geno.owl\",\n",
-      "        \"version\": \"2022-03-05\",\n",
-      "        \"namespacePrefix\": \"GENO\",\n",
-      "        \"iriPrefix\": \"http://purl.obolibrary.org/obo/GENO_\"\n",
-      "      },\n",
-      "      {\n",
-      "        \"id\": \"hgnc\",\n",
-      "        \"name\": \"HUGO Gene Nomenclature Committee\",\n",
-      "        \"url\": \"https://www.genenames.org\",\n",
-      "        \"version\": \"06/01/23\",\n",
-      "        \"namespacePrefix\": \"HGNC\",\n",
-      "        \"iriPrefix\": \"https://www.genenames.org/data/gene-symbol-report/#!/hgnc_id/\"\n",
-      "      },\n",
-      "      {\n",
-      "        \"id\": \"omim\",\n",
-      "        \"name\": \"An Online Catalog of Human Genes and Genetic Disorders\",\n",
-      "        \"url\": \"https://www.omim.org\",\n",
-      "        \"version\": \"January 4, 2023\",\n",
-      "        \"namespacePrefix\": \"OMIM\",\n",
-      "        \"iriPrefix\": \"https://www.omim.org/entry/\"\n",
-      "      },\n",
-      "      {\n",
-      "        \"id\": \"so\",\n",
-      "        \"name\": \"Sequence types and features ontology\",\n",
-      "        \"url\": \"http://purl.obolibrary.org/obo/so.obo\",\n",
-      "        \"version\": \"2021-11-22\",\n",
-      "        \"namespacePrefix\": \"SO\",\n",
-      "        \"iriPrefix\": \"http://purl.obolibrary.org/obo/SO_\"\n",
-      "      },\n",
-      "      {\n",
-      "        \"id\": \"hp\",\n",
-      "        \"name\": \"human phenotype ontology\",\n",
-      "        \"url\": \"http://purl.obolibrary.org/obo/hp.owl\",\n",
-      "        \"version\": \"2023-06-06\",\n",
-      "        \"namespacePrefix\": \"HP\",\n",
-      "        \"iriPrefix\": \"http://purl.obolibrary.org/obo/HP_\"\n",
-      "      }\n",
-      "    ],\n",
-      "    \"phenopacketSchemaVersion\": \"2.0\"\n",
-      "  }\n",
-      "}\n"
-     ]
-    }
-   ],
-   "source": [
-    "json_string = MessageToJson(phenopacket1)\n",
-    "print(json_string)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "52fe4217",
-   "metadata": {},
-   "source": [
-    "<h2>Write phenopackets to file</h2>\n",
-    "<p>The CohortEncoder object has a method to write phenopackets for each of the cases to file.</p>"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 30,
-   "id": "b154cbfa",
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "13"
-      ]
-     },
-     "execution_count": 30,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "Individual.output_individuals_as_phenopackets(individual_list=individuals, \n",
-    "                                              pmid=pmid, \n",
-    "                                              metadata=metadata.to_ga4gh(), \n",
-    "                                              outdir=\"phenopackets\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "ae027cb5",
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  }
- ],
- "metadata": {
-  "kernelspec": {
-   "display_name": "pptvenv",
-   "language": "python",
-   "name": "pptvenv"
-  },
-  "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.10.12"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/pyproject.toml b/pyproject.toml
index 6d45a8dc..2605faca 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -32,7 +32,7 @@ keywords = [
     "GA4GH",
     "HPO"]
 dependencies = [
-    "hpo-toolkit>=0.2.0",
+    "hpo-toolkit>=0.3.0",
     "openpyxl",
     "pandas",
     "phenopackets",
@@ -44,10 +44,6 @@ dynamic = ["version"]
 test = ["pytest"]
 
 
-
-#[project.optional-dependencies]
-#dev = ["black", "bumpver", "isort", "pip-tools", "pytest"]
-
 [project.urls]
 homepage = "https://github.com/monarch-initiative/pyphetools"
 repository = "https://github.com/monarch-initiative/pyphetools.git"
diff --git a/src/pyphetools/__init__.py b/src/pyphetools/__init__.py
index bdc44706..65adc4e0 100644
--- a/src/pyphetools/__init__.py
+++ b/src/pyphetools/__init__.py
@@ -6,7 +6,7 @@
 from . import validation
 
 
-__version__ = "0.6.5"
+__version__ = "0.6.6"
 
 
 __all__ = [
diff --git a/src/pyphetools/creation/__init__.py b/src/pyphetools/creation/__init__.py
index 7c42697e..70a87c8c 100644
--- a/src/pyphetools/creation/__init__.py
+++ b/src/pyphetools/creation/__init__.py
@@ -4,12 +4,15 @@
 from .column_mapper import ColumnMapper
 from .constant_column_mapper import ConstantColumnMapper
 from .custom_column_mapper import CustomColumnMapper
+from .disease import Disease
 from .hgvs_variant import HgvsVariant
 from .hpo_cr import HpoConceptRecognizer
 from .hpo_parser import HpoParser
+from .hpotk_parser import HpoToolkitParser
 from .hp_term import HpTerm
 from .individual import Individual
 from .metadata import MetaData
+from .ontology_qc import OntologyQC
 from .option_column_mapper import OptionColumnMapper
 from .sex_column_mapper import SexColumnMapper
 from .simple_column_mapper import SimpleColumnMapper, SimpleColumnMapperGenerator
@@ -28,12 +31,15 @@
     "ConstantColumnMapper",
     "ColumnMapper",
     "CustomColumnMapper",
+    "Disease",
     "HgvsVariant",
     "HpoConceptRecognizer",
     "HpoParser",
+    "HpoToolkitParser",
     "HpTerm",
     "Individual",
     "MetaData",
+    "OntologyQC",
     "OptionColumnMapper",
     "SexColumnMapper",
     "SimpleColumnMapper",
diff --git a/src/pyphetools/creation/cohort_encoder.py b/src/pyphetools/creation/cohort_encoder.py
index f580fea1..9dffc8ea 100644
--- a/src/pyphetools/creation/cohort_encoder.py
+++ b/src/pyphetools/creation/cohort_encoder.py
@@ -1,13 +1,14 @@
 import pandas as pd
 from math import isnan
 from typing import List, Dict
-import phenopackets as PPkt
 import os
 
 from .age_column_mapper import AgeColumnMapper
 from .constants import Constants
+from .disease import Disease
 from .hpo_cr import HpoConceptRecognizer
 from .individual import Individual
+from .ontology_qc import OntologyQC
 from .sex_column_mapper import SexColumnMapper
 from .variant_column_mapper import VariantColumnMapper
 
@@ -93,6 +94,10 @@ def __init__(self,
         self._pmid = pmid
         self._disease_dictionary = None
         self._delimiter = delimiter
+        ontology = hpo_cr.get_hpo_ontology()
+        if ontology is None:
+            raise ValueError("ontology cannot be None")
+        self._qc = OntologyQC(ontology=ontology)
 
     def preview_dataframe(self):
         """
@@ -144,10 +149,15 @@ def set_disease(self, disease_id, label):
         self._disease_label = label
         self._disease_dictionary = None
 
-    #def set_disease_dictionary(self, disease_d):
-    #    self._disease_dictionary = disease_d
-    #    self._disease_id = None
-    #    self._disease_label = None
+    def set_disease_dictionary(self, disease_d:Dict[str, Disease]):
+        """Set the dictionary of disease ontology terms
+
+        For tables with multiple different diseases, we provide a dictionary that has as key
+        the string used in the original table and as value
+        """
+        self._disease_dictionary = disease_d
+        self._disease_id = None
+        self._disease_label = None
 
     def get_individuals(self) -> List[Individual]:
         """Get a list of all Individual objects in the cohort
@@ -205,8 +215,8 @@ def get_individuals(self) -> List[Individual]:
                 if individual_id not in self._disease_dictionary:
                     raise ValueError(f"Could not find disease link for {individual_id}")
                 disease = self._disease_dictionary.get(individual_id)
-                disease_id = disease.get('id')
-                disease_label = disease.get('label')
+                disease_id = disease.id
+                disease_label = disease.label
                 indi = Individual(individual_id=individual_id, 
                                   sex=sex, 
                                   age=age, 
@@ -215,7 +225,6 @@ def get_individuals(self) -> List[Individual]:
                                   interpretation_list=interpretation_list,
                                   disease_id=disease_id, 
                                   disease_label=disease_label)
-                individuals.append(indi)
             elif self._disease_dictionary is None and self._disease_id is not None and self._disease_label is not None:
                 indi = Individual(individual_id=individual_id, 
                                   sex=sex, 
@@ -224,9 +233,9 @@ def get_individuals(self) -> List[Individual]:
                                   pmid=self._pmid,
                                   interpretation_list=interpretation_list, disease_id=self._disease_id,
                                   disease_label=self._disease_label)
-                individuals.append(indi)
             else:
                 raise ValueError(f"Could not find disease data for '{individual_id}'")
+            hpo_terms = self._qc.clean_terms(indi.hpo_terms)
         return individuals
 
     def output_phenopackets(self, outdir="phenopackets"):
diff --git a/src/pyphetools/creation/disease.py b/src/pyphetools/creation/disease.py
new file mode 100644
index 00000000..14eafe69
--- /dev/null
+++ b/src/pyphetools/creation/disease.py
@@ -0,0 +1,25 @@
+
+
+
+class Disease:
+    """
+    Simple data object to hold ontology id/label for a disease diagnosis
+
+    :param disease_id: a CURIE such as OMIM:600324
+    :type disease_id: str
+    :param disease_label: the name of the disease
+    :type disease_label: str
+    """
+
+    def __init__(self, disease_id:str, disease_label):
+        self._id = disease_id
+        self._label = disease_label
+
+
+    @property
+    def id(self):
+        return self._id
+
+    @property
+    def label(self):
+        return self._label
diff --git a/src/pyphetools/creation/hpo_cr.py b/src/pyphetools/creation/hpo_cr.py
index b5151217..5b0cfcf5 100644
--- a/src/pyphetools/creation/hpo_cr.py
+++ b/src/pyphetools/creation/hpo_cr.py
@@ -27,3 +27,11 @@ def get_term_from_label(self, label) -> HpTerm:
     @abc.abstractmethod
     def initialize_simple_column_maps(self, column_name_to_hpo_label_map, observed, excluded, non_measured=None):
         pass
+
+    @abc.abstractmethod
+    def get_hpo_ontology(self):
+        """
+        :returns: a reference to the HPO-toolkit Ontology object for the HPO
+        :rtype: hpotk.MinimalOntology
+        """
+        pass
diff --git a/src/pyphetools/creation/hpo_exact_cr.py b/src/pyphetools/creation/hpo_exact_cr.py
index 83d7045e..2a157e5b 100644
--- a/src/pyphetools/creation/hpo_exact_cr.py
+++ b/src/pyphetools/creation/hpo_exact_cr.py
@@ -1,3 +1,5 @@
+import hpotk
+
 from .hpo_cr import HpoConceptRecognizer
 from .hp_term import HpTerm
 from .column_mapper import ColumnMapper
@@ -49,7 +51,7 @@ def overlaps(self, other):
 
 class HpoExactConceptRecognizer(HpoConceptRecognizer):
     # self._label_to_id_d, self._id_to_primary_label
-    def __init__(self, label_to_id, id_to_primary_label):
+    def __init__(self, label_to_id, id_to_primary_label, ontology:hpotk.Ontology=None):
         super().__init__()
         if not isinstance(label_to_id, dict):
             raise ValueError("label_to_id_d argument must be dictionary")
@@ -57,6 +59,7 @@ def __init__(self, label_to_id, id_to_primary_label):
             raise ValueError("labels_to_primary_label_d argument must be dictionary")
         self._id_to_primary_label = id_to_primary_label
         self._label_to_id = label_to_id
+        self._ontology = ontology
 
     def parse_cell(self, cell_contents, custom_d=None) -> List[HpTerm]:
         """parse the contents of one table cell
@@ -173,3 +176,10 @@ def initialize_simple_column_maps(self, column_name_to_hpo_label_map, observed,
             mpr = SimpleColumnMapper(hpo_id=hp_term.id, hpo_label=hp_term.label, observed=observed, excluded=excluded)
             simple_mapper_d[column_name] = mpr
         return simple_mapper_d
+
+    def get_hpo_ontology(self):
+        """
+        :returns: a reference to the HPO-toolkit Ontology object for the HPO
+        :rtype: hpotk.MinimalOntology
+        """
+        return self._ontology
diff --git a/src/pyphetools/creation/hpotk_parser.py b/src/pyphetools/creation/hpotk_parser.py
new file mode 100644
index 00000000..65188735
--- /dev/null
+++ b/src/pyphetools/creation/hpotk_parser.py
@@ -0,0 +1,57 @@
+import hpotk
+import os
+from typing import Dict
+from .hpo_cr import HpoConceptRecognizer
+from .hpo_exact_cr import HpoExactConceptRecognizer
+
+HPO_JSON_URL = "http://purl.obolibrary.org/obo/hp/hp.json"
+
+
+class HpoToolkitParser:
+    """
+    Class to retrieve and parse the HPO JSON file using the HPO-Toolkit
+    """
+
+    def __init__(self, hpo_json_file:str=None):
+        if hpo_json_file is not None:
+            if not os.path.isfile(hpo_json_file):
+                raise FileNotFoundError(f"Could not find hp.json file at {hpo_json_file}")
+            self._ontology = hpotk.load_minimal_ontology(hpo_json_file)
+        else:
+            self._ontology = hpotk.load_minimal_ontology(HPO_JSON_URL)
+
+    def get_ontology(self):
+        """
+        :returns: a reference to the HPO
+        :rtype: hpotk.MinimalOntology
+        """
+        return self._ontology
+
+    def get_label_to_id_map(self):
+        """
+        :returns: a map from HPO term labels to HPO ids
+        :rtype: Dict[str,str]
+        """
+        label_to_id_d = {}
+        for t in self._ontology.terms:
+            if t.is_obsolete:
+                continue
+            label_to_id_d[t.name] = t.identifier.value
+        return label_to_id_d
+
+    def get_id_to_label_map(self):
+        """
+        :returns: a map from HPO term ids to HPO labels
+        :rtype: Dict[str,str]
+        """
+        id_to_label_d = {}
+        for t in self._ontology.terms:
+            if t.is_obsolete:
+                continue
+            id_to_label_d[t.identifier.value] = t.name
+        return id_to_label_d
+
+    def get_hpo_concept_recognizer(self) -> HpoConceptRecognizer:
+        return HpoExactConceptRecognizer(label_to_id=self.get_label_to_id_map(),
+                                         id_to_primary_label=self.get_id_to_label_map(),
+                                         ontology=self.get_ontology())
diff --git a/src/pyphetools/creation/individual.py b/src/pyphetools/creation/individual.py
index ce02cb14..e28d694b 100644
--- a/src/pyphetools/creation/individual.py
+++ b/src/pyphetools/creation/individual.py
@@ -1,6 +1,7 @@
 import phenopackets
 import re
 import os
+from typing import List
 from google.protobuf.json_format import MessageToJson
 from .constants import Constants
 from .hgvs_variant import Variant
@@ -55,18 +56,34 @@ def __init__(self, individual_id,
 
     @property
     def id(self):
+        """
+        :returns: the individual identifier
+        :rtype: str
+        """
         return self._individual_id
 
     @property
     def sex(self):
+        """
+        :returns: one of 'MALE', 'FEMALE', 'OTHER', 'UNKNOWN'
+        :rtype: str
+        """
         return self._sex
 
     @property
     def age(self):
+        """
+        :returns: an iso8601 representation of age
+        :rtype: str
+        """
         return self._age
 
     @property
     def hpo_terms(self):
+        """
+        :returns: a list of observed and excluded HPO terms
+        :rtype: List[pyphetools.creation.HpTerm]
+        """
         return self._hpo_terms
 
     @property
@@ -104,11 +121,18 @@ def set_disease(self, disease_id, disease_label):
         self._disease_id = disease_id
         self._disease_label = disease_label
 
+    def set_hpo_terms(self, cleansed_hpo_terms):
+        """
+        :param cleansed_hpo_terms: a list of HpTerm objects that has been cleansed by OntologyQC
+        :type cleansed_hpo_terms: List[pyphetools.creation.HpTerm]
+        """
+        self._hpo_terms = cleansed_hpo_terms
+
     def to_ga4gh_phenopacket(self, metadata, phenopacket_id=None):
         """_summary_
         Transform the data into GA4GH Phenopacket format
-        Returns:
-            _type_: _description_
+        :returns:  a GA4GH Phenopacket representing this individual
+        :
         """
         if not str(type(metadata)) == "<class 'phenopackets.schema.v2.core.meta_data_pb2.MetaData'>":
             raise ValueError(f"metadata argument must be GA4GH Phenopacket Schema MetaData but was {type(metadata)}")
diff --git a/src/pyphetools/creation/ontology_qc.py b/src/pyphetools/creation/ontology_qc.py
new file mode 100644
index 00000000..0a614fdd
--- /dev/null
+++ b/src/pyphetools/creation/ontology_qc.py
@@ -0,0 +1,100 @@
+import hpotk
+from typing import List
+from .hp_term import HpTerm
+from enum import Enum
+
+class Category(Enum):
+    REDUNDANT = 1
+    CONFLICT = 2
+
+
+class QcError:
+    def __init__(self, category:Category, term:HpTerm):
+        self._category = category
+        self._term = term
+
+    def report(self):
+        pass
+
+
+class OntologyQC:
+    """
+    This class performs two kind of checks/cleansing of ontology data
+    1. negated superclass and observed subclass (this is an error in the original data)
+    2. observed superclass and observed subclass (this is a redundancy but arguably not an error)
+
+    """
+
+    def __init__(self, ontology:hpotk.MinimalOntology):
+        self._ontology = ontology
+        self._errors = []
+
+
+    def _fix_conflicts(self, observed_hpo_terms:List[HpTerm], excluded_hpo_terms) -> List[HpTerm]:
+        """
+        This class detects excluded superclasses that have observed subclasses -- a conflict.
+
+        For instance, if an individual is annotated to the terms (1) excluded: Seizure [HP:0001250] and (2)
+        observed - Clonic Seizure [HP:0020221], this is a conflict, because a person with clonic seizure also
+        can be said to have seizure. Here, we assume that the excluded annotation is an error that we
+        want to remove automatically and issue a warning. Thus, in this example, we would remove the
+        annotation excluded: Seizure [HP:0001250], and in general the excluded superclass is removed
+        if this kind of conflict is detected
+
+        :param observed_hpo_terms:list of HPO terms (observed), can be empty
+        :type observed_hpo_terms:List[HpTerm]
+        :param excluded_hpo_terms:list of HPO terms (excluded), can be empty
+        :type excluded_hpo_terms:List[HpTerm]
+        """
+        if len(excluded_hpo_terms) == 0:
+            # i.e., there can be no conflict
+            return observed_hpo_terms
+        all_excluded_term_ids = {term.id for term in excluded_hpo_terms}
+        conflicting_term_id_set = set()
+        for term in observed_hpo_terms:
+            for tid in all_excluded_term_ids:
+                if self._ontology.graph.is_ancestor_of(tid, term.id):
+                    conflicting_term_id_set.add(tid)
+        if len(conflicting_term_id_set) > 0:
+            excluded_hpo_terms = [term for term in excluded_hpo_terms if term.id not in conflicting_term_id_set]
+        observed_hpo_terms.extend(excluded_hpo_terms)
+        return observed_hpo_terms
+
+
+
+
+    def _fix_redundancies(self, hpo_terms:List[HpTerm]) -> List[HpTerm]:
+        all_terms = set(hpo_terms)
+        all_term_ids = {term.id for term in hpo_terms}
+        redundant_term_id_set = set()
+        for term in all_terms:
+            for tid in all_term_ids:
+                # The ancesotr, e.g. Seizure comes first, the other term, e.g. Clonic seizure, second
+                # in the following function call
+                if self._ontology.graph.is_ancestor_of(tid, term.id):
+                    redundant_term_id_set.add(tid)
+        # When we get here, we have scanned all terms for redundant ancestors
+        non_redundant_terms = [ term for term in hpo_terms if term.id not in redundant_term_id_set]
+        if len(redundant_term_id_set) > 0:
+            for tid in redundant_term_id_set:
+                error = QcError(Category.REDUNDANT, tid)
+                self._errors.append(error)
+        return non_redundant_terms
+
+
+
+    def clean_terms(self, hpo_terms:List[HpTerm], fix_conflicts=True, fix_redundancies=True) -> List[HpTerm]:
+        observed_hpo_terms = [term for term in hpo_terms if term.observed]
+        excluded_hpo_terms = [term for term in hpo_terms if not term.observed]
+        self._errors = []
+        if fix_redundancies:
+            observed_hpo_terms = self._fix_redundancies(observed_hpo_terms)
+            excluded_hpo_terms = self._fix_redundancies(excluded_hpo_terms)
+        if fix_conflicts:
+            hpo_terms = self._fix_conflicts(observed_hpo_terms, excluded_hpo_terms)
+        return hpo_terms
+
+    def has_error(self):
+        return len(self._errors) > 0
+
+


Test patch:
diff --git a/test/test_ontology_qc.py b/test/test_ontology_qc.py
new file mode 100644
index 00000000..6a4f58ce
--- /dev/null
+++ b/test/test_ontology_qc.py
@@ -0,0 +1,58 @@
+import unittest
+import os
+from src.pyphetools.creation import HpoToolkitParser, OntologyQC, HpTerm
+
+
+HP_JSON_FILENAME = os.path.join(os.path.dirname(__file__), 'data', 'hp.json')
+
+
+class TestOntologyQC(unittest.TestCase):
+    @classmethod
+    def setUpClass(cls) -> None:
+        parser = HpoToolkitParser(hpo_json_file=HP_JSON_FILENAME)
+        hpo_cr = parser.get_hpo_concept_recognizer()
+        ontology = hpo_cr.get_hpo_ontology()
+        cls._qc = OntologyQC(ontology=ontology)
+
+    def test_non_null(self):
+        self.assertIsNotNone(self._qc)
+
+    def test_conflict(self):
+        arachTerm = HpTerm(hpo_id="HP:0001166", label="Arachnodactyly", observed=True)
+        slenderTerm = HpTerm(hpo_id="HP:0001238", label="Slender finger", observed=False)
+        hpo_terms = [arachTerm, slenderTerm]
+        qc_hpo_terms = self._qc.clean_terms(hpo_terms)
+        self.assertEqual(1, len(qc_hpo_terms))
+
+    def test_do_not_detect_conflict_if_there_is_no_conflict(self):
+        arachTerm = HpTerm(hpo_id="HP:0001166", label="Arachnodactyly", observed=True)
+        # the following is not a conflict and should not be removed
+        hipDislocation = HpTerm(hpo_id="HP:0002827", label="Hip dislocation", observed=False)
+        hpo_terms = [arachTerm, hipDislocation]
+        qc_hpo_terms = self._qc.clean_terms(hpo_terms)
+        self.assertEqual(2, len(qc_hpo_terms))
+
+    def test_do_not_detect_conflict_if_there_is_no_conflict_2(self):
+        """
+        This is not a conflict because the subclass is excluded while the superclass is observed
+        """
+        arachTerm = HpTerm(hpo_id="HP:0001166", label="Arachnodactyly", observed=False)
+        slenderTerm = HpTerm(hpo_id="HP:0001238", label="Slender finger", observed=True)
+        hpo_terms = [arachTerm, slenderTerm]
+        qc_hpo_terms = self._qc.clean_terms(hpo_terms)
+        self.assertEqual(2, len(qc_hpo_terms))
+
+    def test_redundancy(self):
+        arachTerm = HpTerm(hpo_id="HP:0001166", label="Arachnodactyly", observed=True)
+        slenderTerm = HpTerm(hpo_id="HP:0001238", label="Slender finger", observed=True)
+        hpo_terms = [arachTerm, slenderTerm]
+        qc_hpo_terms = self._qc.clean_terms(hpo_terms)
+        self.assertEqual(1, len(qc_hpo_terms))
+
+    def test_do_not_remove_if_not_redundant(self):
+        arachTerm = HpTerm(hpo_id="HP:0001166", label="Arachnodactyly", observed=True)
+        hipDislocation = HpTerm(hpo_id="HP:0002827", label="Hip dislocation", observed=False)
+        hpo_terms = [arachTerm, hipDislocation]
+        qc_hpo_terms = self._qc.clean_terms(hpo_terms)
+        self.assertEqual(2, len(qc_hpo_terms))
+