Repository: adelenelai/onglai-classify-homologues (language: python)

Issue:
Improve packaging
This PR does a few things to improve the packaging in the dev branch:

1. Remove stuff that shouldn't be committed (entire `venv` folder, all `.idea` configuration, mac-specific files like .DS_store, `__pycache__` folders) and add appropriate entries in `.gitignore`
2. Fixes the install config
   - remove `requirements.txt` (this isn't appropriate for packaged code)
   - add `setup.py` which is a necessary companion to `setup.cfg`
3. Update installation documentation and related parts of the README.md


Discussion / hints:

Fix patch:
diff --git a/.DS_Store b/.DS_Store
deleted file mode 100644
index 431ddbf..0000000
Binary files a/.DS_Store and /dev/null differ
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ad99f7f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,402 @@
+
+# Created by https://www.toptal.com/developers/gitignore/api/python,pycharm,jupyternotebooks,macos,linux,windows,intellij
+# Edit at https://www.toptal.com/developers/gitignore?templates=python,pycharm,jupyternotebooks,macos,linux,windows,intellij
+
+### Intellij ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# AWS User-specific
+.idea/**/aws.xml
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn.  Uncomment if using
+# auto-import.
+# .idea/artifacts
+# .idea/compiler.xml
+# .idea/jarRepositories.xml
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+### Intellij Patch ###
+# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
+
+# *.iml
+# modules.xml
+# .idea/misc.xml
+# *.ipr
+
+# Sonarlint plugin
+# https://plugins.jetbrains.com/plugin/7973-sonarlint
+.idea/**/sonarlint/
+
+# SonarQube Plugin
+# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
+.idea/**/sonarIssues.xml
+
+# Markdown Navigator plugin
+# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
+.idea/**/markdown-navigator.xml
+.idea/**/markdown-navigator-enh.xml
+.idea/**/markdown-navigator/
+
+# Cache file creation bug
+# See https://youtrack.jetbrains.com/issue/JBR-2257
+.idea/$CACHE_FILE$
+
+# CodeStream plugin
+# https://plugins.jetbrains.com/plugin/12206-codestream
+.idea/codestream.xml
+
+### JupyterNotebooks ###
+# gitignore template for Jupyter Notebooks
+# website: http://jupyter.org/
+
+.ipynb_checkpoints
+*/.ipynb_checkpoints/*
+
+# IPython
+profile_default/
+ipython_config.py
+
+# Remove previous ipynb_checkpoints
+#   git rm -r .ipynb_checkpoints/
+
+### Linux ###
+*~
+
+# temporary files which can be created if a process still has a handle open of a deleted file
+.fuse_hidden*
+
+# KDE directory preferences
+.directory
+
+# Linux trash folder which might appear on any partition or disk
+.Trash-*
+
+# .nfs files are created when an open file is removed but is still being accessed
+.nfs*
+
+### macOS ###
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+### PyCharm ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+
+# AWS User-specific
+
+# Generated files
+
+# Sensitive or high-churn files
+
+# Gradle
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn.  Uncomment if using
+# auto-import.
+# .idea/artifacts
+# .idea/compiler.xml
+# .idea/jarRepositories.xml
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+
+# Mongo Explorer plugin
+
+# File-based project format
+
+# IntelliJ
+
+# mpeltonen/sbt-idea plugin
+
+# JIRA plugin
+
+# Cursive Clojure plugin
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+
+# Editor-based Rest Client
+
+# Android studio 3.1+ serialized cache file
+
+### PyCharm Patch ###
+# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
+
+# *.iml
+# modules.xml
+# .idea/misc.xml
+# *.ipr
+
+# Sonarlint plugin
+# https://plugins.jetbrains.com/plugin/7973-sonarlint
+
+# SonarQube Plugin
+# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
+
+# Markdown Navigator plugin
+# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
+
+# Cache file creation bug
+# See https://youtrack.jetbrains.com/issue/JBR-2257
+
+# CodeStream plugin
+# https://plugins.jetbrains.com/plugin/12206-codestream
+
+### Python ###
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+#  Usually these files are written by a python script from a template
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+
+# IPython
+
+# pyenv
+#   For a library or package, you might want to ignore these files since the code is
+#   intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+#   However, in case of collaboration, if having platform-specific dependencies or dependencies
+#   having no cross-platform support, pipenv may install dependencies that don't work, or not
+#   install all needed dependencies.
+#Pipfile.lock
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+### Windows ###
+# Windows thumbnail cache files
+Thumbs.db
+Thumbs.db:encryptable
+ehthumbs.db
+ehthumbs_vista.db
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+# End of https://www.toptal.com/developers/gitignore/api/python,pycharm,jupyternotebooks,macos,linux,windows,intellij
diff --git a/README.md b/README.md
index 8d3a2ad..6006e69 100644
--- a/README.md
+++ b/README.md
@@ -6,28 +6,24 @@ Homologous series describe groups of chemical compounds containing a common core
  
  
  
- ## Requirements
- The homologues classification algorithm requires RDKit to be installed and the RDKit environment to be activated. This is best done using conda in the command line:
- 
- ```
- conda create -c conda-forge -n my-rdkit-env rdkit
- 
- conda activate my-rdkit-env
- ```
- 
- More info here: https://www.rdkit.org/docs/Install.html
+## Installation
 
+The code can be installed directly from GitHub with:
 
+```shell
+$ pip install git+https://github.com/adelenelai/classify_homologues.git
+```
 
+The code can be installed in editable mode with:
 
-## Usage
-
-```
-git clone https://github.com/adelenelai/classify_homologues
-cd classify_homologues
-conda activate my-rdkit-env       ## if not already activated
+```shell
+$ git clone https://github.com/adelenelai/classify_homologues
+$ cd classify_homologues
+$ pip install -e .
 ```
 
+## Usage
+
 Then
 ```python classify_homologues.py <SMILES list> <Labels list> <repeating unit> 2>log```
 
diff --git a/classify_homols.py b/classify_homols.py
deleted file mode 100644
index a744d21..0000000
--- a/classify_homols.py
+++ /dev/null
@@ -1,292 +0,0 @@
-import os
-import sys
-import rdkit.Chem as Chem
-from rdkit.Chem import AllChem
-import rdkit.Chem.rdchem as rdchem
-import rdkit.Chem.Draw as Draw
-import rdkit.Chem.Descriptors
-from rdkit.Chem import PandasTools
-from rdkit.Chem.Draw import IPythonConsole, MolsToGridImage
-PandasTools.RenderImagesInAllDataFrames(images=True)
-import pandas as pd
-import numpy as np
-import matplotlib.pyplot as plt
-from rdkit.Chem import rdFMCS
-from itertools import compress
-from collections import defaultdict, OrderedDict, Counter
-from timeit import default_timer as timer
-from contextlib import redirect_stderr
-
-#from https://sourceforge.net/p/rdkit/mailman/rdkit-discuss/thread/CAHGTkV8sdfb4Q7FLn9C5MTwrqiJjHtnXK%2Bmz2SY3_4j2eAtevQ%40mail.gmail.com/#msg36477772
-from rdkit.Chem.Draw import rdMolDraw2D
-try:
-    import Image
-except ImportError:
-    from PIL import Image
-from io import BytesIO
-
-def DrawMolsZoomed(mols, legends, molsPerRow=3, subImgSize=(300, 300)):#, leg): #https://www.rdkit.org/docs/source/rdkit.Chem.Draw.rdMolDraw2D.html#rdkit.Chem.Draw.rdMolDraw2D.MolDraw2D
-    nRows = len(mols) // molsPerRow
-    if len(mols) % molsPerRow: nRows += 1
-    fullSize = (molsPerRow * subImgSize[0], nRows * subImgSize[1])
-    full_image = Image.new('RGBA', fullSize )
-    for ii, mol in enumerate(mols):
-        if mol.GetNumConformers() == 0:
-            AllChem.Compute2DCoords(mol)
-        le = legends[ii]
-        column = ii % molsPerRow
-        row = ii // molsPerRow
-        offset = ( column*subImgSize[0], row * subImgSize[1] )
-        d2d = rdMolDraw2D.MolDraw2DCairo(subImgSize[0], subImgSize[1])
-        d2d.DrawMolecule(mol,legend=le)
-        d2d.FinishDrawing()
-        sub = Image.open(BytesIO(d2d.GetDrawingText()))
-        full_image.paste(sub,box=offset)
-    return full_image
-
-
-Chem.WrapLogs()
-
-#from contextlib import redirect_stdout, redirect_stderr
-#import io, logging
-#import externallib
-#logging.basicConfig(filename='error.log', level=logging.DEBUG)
-
-#f = io.StringIO()
-#with redirect_stdout(f), redirect_stderr(f):
-#    result = externallib.check_result()
-#logging.info(f.getvalue())
-#print(result)
-#https://www.codeforests.com/2020/11/05/python-suppress-stdout-and-stderr/
-
-
-#mols
-with open(sys.argv[1]) as f:
-    smiles = [line.strip().replace('"','') for line in f]
-
-mols = [AllChem.MolFromSmiles(smile) for smile in smiles]
-
-#labels
-with open(sys.argv[2]) as f:
-    labels = [line.strip().replace('"','') for line in f]
-
-df = pd.DataFrame({ "SMILES":smiles,
-                     "Mols":mols,
-                    "Labels":labels
-                  })
-
-#read in alkyl chains
-#with open('alkylchains.txt') as p:
-#    smiles_alkylchains = [line.strip() for line in p]
-
-#repeating unit
-smiles_ru = []
-[smiles_ru.append(sys.argv[3]*i) for i in range(1,31)]
-
-
-#set up alkyl chains
-ru = [AllChem.MolFromSmiles(smi) for smi in smiles_ru] #includes C and CC
-
-#prepare to generate MergeQueryHs
-ru_explicitH = [Chem.AddHs(r,onlyOnAtoms=(range(1,r.GetNumAtoms()-1))) for r in ru[2:]]
-#automatically discards meth- and eth-
-
-#with implicitHs i.e. MergeQueryHs
-ru_implicit_queryH = [Chem.MergeQueryHs(m) for m in ru_explicitH]
-#ru_implicit_queryH = ru
-#initialise foo - the 2d array showing whether there are alkyl substructure matches (1 or 0)
-foo = np.zeros((len(mols), len(ru_implicit_queryH)))
-
-for a,b in enumerate(mols):
-    for i,j in enumerate(ru_implicit_queryH):
-        foo[a,i] = mols[a].HasSubstructMatch(j) #gives 1s and 0s in alkyl chain matching
-
-#analyse foo_array_sums
-foo_array_sums = []
-length_ru_chains_to_chop = []
-for x,y in enumerate(foo):
-    foo_array_sums.append(int(np.sum(foo[x])))
-    length_ru_chains_to_chop.append(foo_array_sums[x] + 2) # n = sum + 2, where n is the length of C chain to chop
-
-#how many have no alkyl chains? i.e. value = 0
-n_mols_no_ru = foo_array_sums.count(0)
-print(str(n_mols_no_ru) + " mols have no repeating unit chains of minimum 3 repeating units in length.")
-#remove mols with no alkyl matches
-fil_ru = []
-fil_ru = [bool(x) for x in foo_array_sums] #those which are False have array_sum = 0 i.e. no alkyls
-mols_with_ru = list(compress(mols,fil_ru))
-labels_mols_with_ru = list(compress(labels,fil_ru))
-#len(mols_with_alkyls)
-
-mols_no_ru_matches = list(compress(mols, [not i for i in fil_ru]))
-labels_mols_no_ru_matches = list(compress(labels, [not i for i in fil_ru]))
-#len(mols_no_alkyl_matches)
-
-#redo chopping and dictionary generation using mols list: mols_with_alkyls
-#initialise 2d array to do longest alkyl chain matching
-foo = np.zeros((len(mols_with_ru), len(ru_implicit_queryH)))
-for a,b in enumerate(mols_with_ru):
-    for i,j in enumerate(ru_implicit_queryH):
-        foo[a,i] = mols_with_ru[a].HasSubstructMatch(j) #1s and 0s in alkyl chain matching
-
-#start 2-step removal in one go without generating new idxs
-##
-#Step 1
-cores = list()
-patt1 = list()
-for x,y in enumerate(mols_with_ru):
-    patt1.append(ru_implicit_queryH[int(np.sum(foo[x])-1)]) #cannot use extend; Mol object is not iterable
-    cores.append(AllChem.DeleteSubstructs(y,patt1[x]))
-
-#initialise 2d array for second removal
-goo = np.zeros((len(mols_with_ru), len(ru_implicit_queryH)))
-
-for a,b in enumerate(cores):
-    for i,j in enumerate(ru_implicit_queryH):
-        goo[a,i] = cores[a].HasSubstructMatch(j)
-
-#2-step removal in one go without generating new idxs
-##
-#Step 2
-cores2 = list()
-patt2 = list()
-for x,y in enumerate(cores):
-    patt2.append(ru_implicit_queryH[int(np.sum(goo[x])-1)]) #if np.sum is 0, could have issues
-    cores2.append(AllChem.DeleteSubstructs(y,patt2[x]))
-
-#isolate empty cores after first chopping
-#happens when mol is 100% made of RU
-empty_cores_idx = [i for i,j in enumerate(cores) if j.GetNumAtoms()==0]
-
-
-#isolate Mol and Label with empty core after first chopping i.e. entire mol is made of ru
-mols_made_of_ru = [j for i,j in enumerate(mols_with_ru) if (i in empty_cores_idx)]
-labels_made_of_ru = [j for i,j in enumerate(labels_mols_with_ru) if (i in empty_cores_idx)]
-
-#finalise lists after filtering out mols_made_of_ru
-mols_with_ru = [j for i,j in enumerate(mols_with_ru) if (i not in empty_cores_idx)]
-labels_mols_with_ru = [j for i,j in enumerate(labels_mols_with_ru) if (i not in empty_cores_idx)]
-
-#isolate non-empty cores after chopping
-cores2_nonempty = [j for i,j in enumerate(cores2) if j.GetNumAtoms()>0]
-
- #make output dir
-os.makedirs("output"+"/")
-if len(mols_made_of_ru) >0:
-    pure_repeating_units = DrawMolsZoomed(mols_made_of_ru,labels_made_of_ru)
-    pure_repeating_units.save("output/mols_pure_repeating_units.png")
-
-#filter out row with empty core after first chopping from all cols and output
-patt1 = [q for p,q in enumerate(patt1) if (p not in empty_cores_idx)]
-cores = [q for p,q in enumerate(cores) if (p not in empty_cores_idx)]
-patt2 = [q for p,q in enumerate(patt2) if (p not in empty_cores_idx)]
-cores2 = [q for p,q in enumerate(cores2) if (p not in empty_cores_idx)]
-
-
-
-#first convert to smarts, then molfromsmarts, then sanitize
-cores2_nonempty_smarts = [Chem.rdmolfiles.MolToSmarts(co) for co in cores2_nonempty]
-cores2_nonempty_molfromsmarts = [Chem.MolFromSmarts(co) for co in cores2_nonempty_smarts] #generates QueryAtoms
-[Chem.SanitizeMol(co) for co in cores2_nonempty_molfromsmarts]
-#get molfrags
-cores2_nonempty_molfrags = [Chem.GetMolFrags(co, asMols=True) for co in cores2_nonempty_molfromsmarts]
-#get the largest molfrag of all molfrags
-cores2_nonempty_largest_molfrag = []
-for i,j in enumerate(cores2_nonempty_molfrags):
-    cores2_nonempty_largest_molfrag.append(max(cores2_nonempty_molfrags[i], default=cores2_nonempty_molfrags[i], key=lambda m:m.GetNumAtoms()))
-
-#build df to summarise SS match and chopping steps
-imp_df_nonempty= pd.DataFrame({#"Smiles":smiles,
-                   #"Mols":mols,
-                    "Mols": mols_with_ru,
-                    "Labels": labels_mols_with_ru,
-                    "patt1": [j for i,j in enumerate(patt1) if cores2[i].GetNumAtoms()>0],
-                    "Cores": [j for i,j in enumerate(cores) if cores2[i].GetNumAtoms()>0],
-                    "patt2": [j for i,j in enumerate(patt2) if cores2[i].GetNumAtoms()>0],
-                    "Cores2": cores2_nonempty,
-                    "LargestMolFrag_sanitised": cores2_nonempty_largest_molfrag
-                    })#"cano_smiles_cores2": cores2_cano_smiles
-
-#get canonical smiles of largest molfrag
-cores2_nonempty_largest_molfrag_smiles = [Chem.MolToSmiles(co) for co in cores2_nonempty_largest_molfrag]
-cores2_nonempty_largest_molfrag_cano_smiles = [Chem.CanonSmiles(smi) for smi in cores2_nonempty_largest_molfrag_smiles]
-
-#populate new column in df with corresponding  cores2_nonempty_largestmolfrag_canosmiles for each row
-imp_df_nonempty["canoSMILES_LargestMolfrag_sanitised"] = cores2_nonempty_largest_molfrag_cano_smiles
-
-#assign SeriesNo to only those series with >1 member
-imp_df_nonempty['SeriesNo'] = imp_df_nonempty.groupby('canoSMILES_LargestMolfrag_sanitised').filter(lambda group: len(group) > 1).groupby('canoSMILES_LargestMolfrag_sanitised').ngroup()
-
-
-#merge imp_df_nonempty with df on mol
-result = pd.merge(df, imp_df_nonempty, how="left", on=["Mols","Labels"])
-
-#annotate no_alkyl mols AND series with 1 member to have negative SeriesNo
-result['SeriesNo'] = result['SeriesNo'].fillna(-1)
-result.SeriesNo = result.SeriesNo.astype(int)
-
-
-#calc further identifiers and descr; write into log file
-with open('log.txt', 'w') as f:
-    with redirect_stderr(f):
-        inchis = [Chem.inchi.MolToInchi(i) for i in result.Mols]
-        inchikeys = [Chem.inchi.MolToInchiKey(i) for i in result.Mols]
-        mf = [Chem.rdMolDescriptors.CalcMolFormula(i) for i in result.Mols]
-        monoiso_mass = [round(Chem.Descriptors.ExactMolWt(i),4) for i in result.Mols]
-
-out = result[["SeriesNo","Labels","canoSMILES_LargestMolfrag_sanitised","SMILES", ]].copy()
-out['InChI'] = inchis
-out['InChIKey'] = inchikeys
-out['molecular_formula'] = mf
-out['monoisotopic_mass'] = monoiso_mass
-out.rename(columns={"SeriesNo":"series_no", "Labels":"series_name", "canoSMILES_LargestMolfrag_sanitised": "common_core"},inplace=True)
-out.to_csv('output/' + 'classified_series.csv',index=False)
-
-#plots per group - only series which have >1 member i.e. actual series
-result_pos_serno = result[result["SeriesNo"] > -1]
-#legends
-lgs = [i for i in result_pos_serno.groupby('canoSMILES_LargestMolfrag_sanitised').Labels.apply(list)]
-for i,j in enumerate(lgs):
-    lgs[i] = lgs[i] + ["core"]
-
-grpdmols = result_pos_serno.groupby('canoSMILES_LargestMolfrag_sanitised').SMILES.apply(list) #lists of SMILES
-for i,j in enumerate(grpdmols):
-    grpdmols[i] = grpdmols[i] + [grpdmols.keys()[i]]
-
-grpdmols = [[Chem.MolFromSmiles(s) for s in g] for g in grpdmols]
-
-list_grid_images = []
-for i,j in enumerate(grpdmols):
-    list_grid_images.append(DrawMolsZoomed(grpdmols[i],legends=lgs[i],molsPerRow=5))
-
-#plot nans i.e. those with no alkyls and therefore not classified
-#print(str(len(mols_no_alkyl_matches)) + ", " + str(len(labels_mols_no_alkyl_matches)))
-if len(mols_no_ru_matches) > 0:
-    nans = DrawMolsZoomed(mols=mols_no_ru_matches, legends=labels_mols_no_ru_matches, molsPerRow=5)
-    nans.save("output/" + "no_repeating_unit_matches.png")
-#print(len(mols_no_alkyl_matches))
-#nans = DrawMolsZoomed(mols=mols_no_alkyl_matches, legends=labels_mols_no_alkyl_matches, molsPerRow=5)
-#nans.save("output/" + "no_alkyl_matches.png")
-
-#save each plot per group
-[img.save("output/" + str(idx) + ".png") for idx,img in enumerate(list_grid_images)]
-
-
-#plot mols with alkyls but are 1-member series (i.e. not actually series)
-#SeriesNo = -1, SMILES is not empty
-
-onememseries = result.loc[(result['SeriesNo'] == -1) & (result['canoSMILES_LargestMolfrag_sanitised'].notnull())]
-if len(onememseries.Mols) >0:
-    mols_onememseries = [i for i in onememseries.Mols]
-    labs_onememseries = [i for i in onememseries.Labels]
-    pl_onememseries = DrawMolsZoomed(mols_onememseries,labs_onememseries,molsPerRow=5)
-    pl_onememseries.save("output/non_series_containing_repeating_unit.png")
-
-num_series = result.SeriesNo.max()
-if num_series < 0:
-    num_series= 0
-
-#sys.stderr = old_stderr
-#assert sio.getvalue() != ""
-
-print("Homologue classification complete! " + str(num_series+1) + " series classified." )
diff --git a/log b/log
deleted file mode 100644
index cfcb22b..0000000
--- a/log
+++ /dev/null
@@ -1,16 +0,0 @@
-[14:05:10] WARNING: Omitted undefined stereo
-[14:05:10] WARNING: Omitted undefined stereo
-[14:05:10] WARNING: Omitted undefined stereo
-[14:05:10] WARNING: Omitted undefined stereo
-[14:05:10] WARNING: Omitted undefined stereo
-[14:05:10] WARNING: Omitted undefined stereo
-[14:05:10] WARNING: Omitted undefined stereo
-[14:05:10] WARNING: Omitted undefined stereo
-[14:05:10] WARNING: Omitted undefined stereo
-[14:05:10] WARNING: Omitted undefined stereo
-[14:05:10] WARNING: Omitted undefined stereo
-[14:05:10] WARNING: Omitted undefined stereo
-[14:05:10] WARNING: Omitted undefined stereo
-[14:05:10] WARNING: Omitted undefined stereo
-[14:05:10] WARNING: Omitted undefined stereo
-[14:05:10] WARNING: Omitted undefined stereo
diff --git a/output_CCO_3_eawagsurf/0.png b/output_CCO_3_eawagsurf/0.png
new file mode 100644
index 0000000..2293c42
Binary files /dev/null and b/output_CCO_3_eawagsurf/0.png differ
diff --git a/output_CCO_3_eawagsurf/1.png b/output_CCO_3_eawagsurf/1.png
new file mode 100644
index 0000000..03285aa
Binary files /dev/null and b/output_CCO_3_eawagsurf/1.png differ
diff --git a/output_CCO_3_eawagsurf/2.png b/output_CCO_3_eawagsurf/2.png
new file mode 100644
index 0000000..3fa8b59
Binary files /dev/null and b/output_CCO_3_eawagsurf/2.png differ
diff --git a/output_CCO_3_eawagsurf/3.png b/output_CCO_3_eawagsurf/3.png
new file mode 100644
index 0000000..6560b32
Binary files /dev/null and b/output_CCO_3_eawagsurf/3.png differ
diff --git a/output_CCO_3_eawagsurf/4.png b/output_CCO_3_eawagsurf/4.png
new file mode 100644
index 0000000..4d1526f
Binary files /dev/null and b/output_CCO_3_eawagsurf/4.png differ
diff --git a/output_CCO_3_eawagsurf/classified_series.csv b/output_CCO_3_eawagsurf/classified_series.csv
new file mode 100644
index 0000000..9a96aa9
--- /dev/null
+++ b/output_CCO_3_eawagsurf/classified_series.csv
@@ -0,0 +1,176 @@
+series_no,series_name,common_core,SMILES,InChI,InChIKey,molecular_formula,monoisotopic_mass
+-1,C10-LAS,,OS(=O)(=O)c1ccc(cc1)C(CCCCC)CCCC,"InChI=1S/C16H26O3S/c1-3-5-7-9-14(8-6-4-2)15-10-12-16(13-11-15)20(17,18)19/h10-14H,3-9H2,1-2H3,(H,17,18,19)",KIIODTIGNUGDLO-UHFFFAOYSA-N,C16H26O3S,298.1603
+-1,C11-LAS,,OS(=O)(=O)c1ccc(cc1)C(CCCCCC)CCCC,"InChI=1S/C17H28O3S/c1-3-5-7-8-10-15(9-6-4-2)16-11-13-17(14-12-16)21(18,19)20/h11-15H,3-10H2,1-2H3,(H,18,19,20)",FERBTPHUEYEGDN-UHFFFAOYSA-N,C17H28O3S,312.1759
+-1,C12-LAS,,OS(=O)(=O)c1ccc(cc1)C(CCCCCCC)CCCC,"InChI=1S/C18H30O3S/c1-3-5-7-8-9-11-16(10-6-4-2)17-12-14-18(15-13-17)22(19,20)21/h12-16H,3-11H2,1-2H3,(H,19,20,21)",FQWWBDRIEVYQEW-UHFFFAOYSA-N,C18H30O3S,326.1916
+-1,C13-LAS,,OS(=O)(=O)c1ccc(cc1)C(CCCCCCC)CCCCC,"InChI=1S/C19H32O3S/c1-3-5-7-8-10-12-17(11-9-6-4-2)18-13-15-19(16-14-18)23(20,21)22/h13-17H,3-12H2,1-2H3,(H,20,21,22)",DKWBEYOUIOCBBC-UHFFFAOYSA-N,C19H32O3S,340.2072
+-1,C14-LAS,,OS(=O)(=O)c1ccc(cc1)C(CCCCCCC)CCCCCC,"InChI=1S/C20H34O3S/c1-3-5-7-9-11-13-18(12-10-8-6-4-2)19-14-16-20(17-15-19)24(21,22)23/h14-18H,3-13H2,1-2H3,(H,21,22,23)",HFNZFDCGFGXPHN-UHFFFAOYSA-N,C20H34O3S,354.2229
+-1,C4-SPC,,OS(=O)(=O)c1ccc(cc1)C(CC(=O)O)C,"InChI=1S/C10H12O5S/c1-7(6-10(11)12)8-2-4-9(5-3-8)16(13,14)15/h2-5,7H,6H2,1H3,(H,11,12)(H,13,14,15)",MRXFSOHFNUZITK-UHFFFAOYSA-N,C10H12O5S,244.0405
+-1,C5-SPC,,OS(=O)(=O)c1ccc(cc1)C(CC(=O)O)CC,"InChI=1S/C11H14O5S/c1-2-8(7-11(12)13)9-3-5-10(6-4-9)17(14,15)16/h3-6,8H,2,7H2,1H3,(H,12,13)(H,14,15,16)",LCPMSBWWWRJQSM-UHFFFAOYSA-N,C11H14O5S,258.0562
+-1,C6-SPC,,OS(=O)(=O)c1ccc(cc1)C(CC(=O)O)CCC,"InChI=1S/C12H16O5S/c1-2-3-10(8-12(13)14)9-4-6-11(7-5-9)18(15,16)17/h4-7,10H,2-3,8H2,1H3,(H,13,14)(H,15,16,17)",RIRZRXPTDYFPNW-UHFFFAOYSA-N,C12H16O5S,272.0718
+-1,C7-SPC,,OS(=O)(=O)c1ccc(cc1)C(CCCCC(=O)O)C,"InChI=1S/C13H18O5S/c1-10(4-2-3-5-13(14)15)11-6-8-12(9-7-11)19(16,17)18/h6-10H,2-5H2,1H3,(H,14,15)(H,16,17,18)",OGZPAXOHMKETJT-UHFFFAOYSA-N,C13H18O5S,286.0875
+-1,C8-SPC,,OS(=O)(=O)c1ccc(cc1)C(CCCCCC(=O)O)C,"InChI=1S/C14H20O5S/c1-11(5-3-2-4-6-14(15)16)12-7-9-13(10-8-12)20(17,18)19/h7-11H,2-6H2,1H3,(H,15,16)(H,17,18,19)",RPNJYFZZXFVGOF-UHFFFAOYSA-N,C14H20O5S,300.1031
+-1,C9-SPC,,OS(=O)(=O)c1ccc(cc1)C(CCCCCCC(=O)O)C,"InChI=1S/C15H22O5S/c1-12(6-4-2-3-5-7-15(16)17)13-8-10-14(11-9-13)21(18,19)20/h8-12H,2-7H2,1H3,(H,16,17)(H,18,19,20)",ZXGROFOELRCPHY-UHFFFAOYSA-N,C15H22O5S,314.1188
+-1,C10-SPC,,OS(=O)(=O)c1ccc(cc1)C(CCCCCCCC(=O)O)C,"InChI=1S/C16H24O5S/c1-13(7-5-3-2-4-6-8-16(17)18)14-9-11-15(12-10-14)22(19,20)21/h9-13H,2-8H2,1H3,(H,17,18)(H,19,20,21)",JGRCUWRTODYDCN-UHFFFAOYSA-N,C16H24O5S,328.1344
+-1,C11-SPC,,OS(=O)(=O)c1ccc(cc1)C(CCCCCCCC(=O)O)CC,"InChI=1S/C17H26O5S/c1-2-14(8-6-4-3-5-7-9-17(18)19)15-10-12-16(13-11-15)23(20,21)22/h10-14H,2-9H2,1H3,(H,18,19)(H,20,21,22)",OVWFNJXSFDTEDP-UHFFFAOYSA-N,C17H26O5S,342.1501
+-1,C12-SPC,,OS(=O)(=O)c1ccc(cc1)C(CCCC(=O)O)CCCCCCC,"InChI=1S/C18H28O5S/c1-2-3-4-5-6-8-15(9-7-10-18(19)20)16-11-13-17(14-12-16)24(21,22)23/h11-15H,2-10H2,1H3,(H,19,20)(H,21,22,23)",TVQYAXFZCFPPBL-UHFFFAOYSA-N,C18H28O5S,356.1657
+-1,C13-SPC,,OS(=O)(=O)c1ccc(cc1)C(CCCCC(=O)O)CCCCCCC,"InChI=1S/C19H30O5S/c1-2-3-4-5-6-9-16(10-7-8-11-19(20)21)17-12-14-18(15-13-17)25(22,23)24/h12-16H,2-11H2,1H3,(H,20,21)(H,22,23,24)",HUKHLEYBPZBAKT-UHFFFAOYSA-N,C19H30O5S,370.1814
+-1,C14-SPC,,OS(=O)(=O)c1ccc(cc1)C(CCCCCC(=O)O)CCCCCCC,"InChI=1S/C20H32O5S/c1-2-3-4-5-7-10-17(11-8-6-9-12-20(21)22)18-13-15-19(16-14-18)26(23,24)25/h13-17H,2-12H2,1H3,(H,21,22)(H,23,24,25)",OYYPDDVTBYAMPI-UHFFFAOYSA-N,C20H32O5S,384.197
+-1,C15-SPC,,OS(=O)(=O)c1ccc(cc1)C(CCCCCCC(=O)O)CCCCCCC,"InChI=1S/C21H34O5S/c1-2-3-4-5-8-11-18(12-9-6-7-10-13-21(22)23)19-14-16-20(17-15-19)27(24,25)26/h14-18H,2-13H2,1H3,(H,22,23)(H,24,25,26)",PLFLJSZNOZLLDW-UHFFFAOYSA-N,C21H34O5S,398.2127
+-1,SPA-3DC,,OS(=O)(=O)c1ccc(cc1)C(CC(=O)O)CC(=O)O,"InChI=1S/C11H12O7S/c12-10(13)5-8(6-11(14)15)7-1-3-9(4-2-7)19(16,17)18/h1-4,8H,5-6H2,(H,12,13)(H,14,15)(H,16,17,18)",JZYCHTVMKGVCNJ-UHFFFAOYSA-N,C11H12O7S,288.0304
+-1,SPA-4DC,,OS(=O)(=O)c1ccc(cc1)C(CC(=O)O)CCC(=O)O,"InChI=1S/C12H14O7S/c13-11(14)6-3-9(7-12(15)16)8-1-4-10(5-2-8)20(17,18)19/h1-2,4-5,9H,3,6-7H2,(H,13,14)(H,15,16)(H,17,18,19)",NJBHOBKMQCLLAD-UHFFFAOYSA-N,C12H14O7S,302.046
+-1,SPA-5DC,,OS(=O)(=O)c1ccc(cc1)C(CC(=O)O)CCCC(=O)O,"InChI=1S/C13H16O7S/c14-12(15)3-1-2-10(8-13(16)17)9-4-6-11(7-5-9)21(18,19)20/h4-7,10H,1-3,8H2,(H,14,15)(H,16,17)(H,18,19,20)",IUPLCGFARCPRDU-UHFFFAOYSA-N,C13H16O7S,316.0617
+-1,SPA-6DC,,OS(=O)(=O)c1ccc(cc1)C(CCC(=O)O)CCCC(=O)O,"InChI=1S/C14H18O7S/c15-13(16)3-1-2-10(6-9-14(17)18)11-4-7-12(8-5-11)22(19,20)21/h4-5,7-8,10H,1-3,6,9H2,(H,15,16)(H,17,18)(H,19,20,21)",ITNHKYWGMBIQRF-UHFFFAOYSA-N,C14H18O7S,330.0773
+-1,SPA-7DC,,OS(=O)(=O)c1ccc(cc1)C(CCC(=O)O)CCCCC(=O)O,"InChI=1S/C15H20O7S/c16-14(17)4-2-1-3-11(7-10-15(18)19)12-5-8-13(9-6-12)23(20,21)22/h5-6,8-9,11H,1-4,7,10H2,(H,16,17)(H,18,19)(H,20,21,22)",OIZCNNRHGMISNB-UHFFFAOYSA-N,C15H20O7S,344.093
+-1,SPA-8DC,,OS(=O)(=O)c1ccc(cc1)C(CCC(=O)O)CCCCCC(=O)O,"InChI=1S/C16H22O7S/c17-15(18)5-3-1-2-4-12(8-11-16(19)20)13-6-9-14(10-7-13)24(21,22)23/h6-7,9-10,12H,1-5,8,11H2,(H,17,18)(H,19,20)(H,21,22,23)",KHBACNRGVMJHTA-UHFFFAOYSA-N,C16H22O7S,358.1086
+-1,SPA-9DC,,OS(=O)(=O)c1ccc(cc1)C(CCC(=O)O)CCCCCCC(=O)O,"InChI=1S/C17H24O7S/c18-16(19)6-4-2-1-3-5-13(9-12-17(20)21)14-7-10-15(11-8-14)25(22,23)24/h7-8,10-11,13H,1-6,9,12H2,(H,18,19)(H,20,21)(H,22,23,24)",UULYWQRKZQDLDC-UHFFFAOYSA-N,C17H24O7S,372.1243
+-1,SPA-10DC,,OS(=O)(=O)c1ccc(cc1)C(CCC(=O)O)CCCCCCCC(=O)O,"InChI=1S/C18H26O7S/c19-17(20)7-5-3-1-2-4-6-14(10-13-18(21)22)15-8-11-16(12-9-15)26(23,24)25/h8-9,11-12,14H,1-7,10,13H2,(H,19,20)(H,21,22)(H,23,24,25)",ROWMJCLRTQACGM-UHFFFAOYSA-N,C18H26O7S,386.1399
+-1,SPA-11DC,,OS(=O)(=O)c1ccc(cc1)C(CCCCC(=O)O)CCCCCCC(=O)O,"InChI=1S/C19H28O7S/c20-18(21)9-4-2-1-3-7-15(8-5-6-10-19(22)23)16-11-13-17(14-12-16)27(24,25)26/h11-15H,1-10H2,(H,20,21)(H,22,23)(H,24,25,26)",BLAGYSGUDRRKNH-UHFFFAOYSA-N,C19H28O7S,400.1556
+-1,SPA-12DC,,OS(=O)(=O)c1ccc(cc1)C(CCCCC(=O)O)CCCCCCCC(=O)O,"InChI=1S/C20H30O7S/c21-19(22)10-5-3-1-2-4-8-16(9-6-7-11-20(23)24)17-12-14-18(15-13-17)28(25,26)27/h12-16H,1-11H2,(H,21,22)(H,23,24)(H,25,26,27)",HDGMOQRHBVJECH-UHFFFAOYSA-N,C20H30O7S,414.1712
+-1,SPA-13DC,,OS(=O)(=O)c1ccc(cc1)C(CCCCCC(=O)O)CCCCCCCC(=O)O,"InChI=1S/C21H32O7S/c22-20(23)11-7-3-1-2-5-9-17(10-6-4-8-12-21(24)25)18-13-15-19(16-14-18)29(26,27)28/h13-17H,1-12H2,(H,22,23)(H,24,25)(H,26,27,28)",VTKCLJNXLCUBHY-UHFFFAOYSA-N,C21H32O7S,428.1869
+-1,SPA-14DC,,OS(=O)(=O)c1ccc(cc1)C(CCCCCCCC(=O)O)CCCCCCC(=O)O,"InChI=1S/C22H34O7S/c23-21(24)12-8-3-1-2-6-10-18(11-7-4-5-9-13-22(25)26)19-14-16-20(17-15-19)30(27,28)29/h14-18H,1-13H2,(H,23,24)(H,25,26)(H,27,28,29)",YFULOBRNUUGPCM-UHFFFAOYSA-N,C22H34O7S,442.2025
+-1,SPA-15DC,,OS(=O)(=O)c1ccc(cc1)C(CCCCCCCC(=O)O)CCCCCCCC(=O)O,"InChI=1S/C23H36O7S/c24-22(25)13-9-5-1-3-7-11-19(12-8-4-2-6-10-14-23(26)27)20-15-17-21(18-16-20)31(28,29)30/h15-19H,1-14H2,(H,24,25)(H,26,27)(H,28,29,30)",XBEVYKVBIAOJPI-UHFFFAOYSA-N,C23H36O7S,456.2182
+-1,C6-DATS,,OS(=O)(=O)c1ccc2c(c1)C(CCC2C)C,"InChI=1S/C12H16O3S/c1-8-3-4-9(2)12-7-10(16(13,14)15)5-6-11(8)12/h5-9H,3-4H2,1-2H3,(H,13,14,15)",FMSLBJBLYXJZOD-UHFFFAOYSA-N,C12H16O3S,240.082
+-1,C7-DATS,,OS(=O)(=O)c1ccc2c(c1)C(CCC2C)CC,"InChI=1S/C13H18O3S/c1-3-10-5-4-9(2)12-7-6-11(8-13(10)12)17(14,15)16/h6-10H,3-5H2,1-2H3,(H,14,15,16)",QYBZLYLYFRDAFN-UHFFFAOYSA-N,C13H18O3S,254.0977
+-1,C8-DATS,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CC)CC,"InChI=1S/C14H20O3S/c1-3-10-5-6-11(4-2)14-9-12(18(15,16)17)7-8-13(10)14/h7-11H,3-6H2,1-2H3,(H,15,16,17)",WTJWYVHBXQXPPA-UHFFFAOYSA-N,C14H20O3S,268.1133
+-1,C9-DATS,,OS(=O)(=O)c1ccc2c(c1)C(CCC2C)CCCC,"InChI=1S/C15H22O3S/c1-3-4-5-12-7-6-11(2)14-9-8-13(10-15(12)14)19(16,17)18/h8-12H,3-7H2,1-2H3,(H,16,17,18)",OLFWXCLPJNCKDG-UHFFFAOYSA-N,C15H22O3S,282.129
+-1,C10-DATS,,OS(=O)(=O)c1ccc2c(c1)C(CCC2C)CCCCC,"InChI=1S/C16H24O3S/c1-3-4-5-6-13-8-7-12(2)15-10-9-14(11-16(13)15)20(17,18)19/h9-13H,3-8H2,1-2H3,(H,17,18,19)",RNUUGPYDXUVEBT-UHFFFAOYSA-N,C16H24O3S,296.1446
+-1,C11-DATS,,OS(=O)(=O)c1ccc2c(c1)C(CCC2C)CCCCCC,"InChI=1S/C17H26O3S/c1-3-4-5-6-7-14-9-8-13(2)16-11-10-15(12-17(14)16)21(18,19)20/h10-14H,3-9H2,1-2H3,(H,18,19,20)",HEVBZFSGAUNHRK-UHFFFAOYSA-N,C17H26O3S,310.1603
+-1,C12-DATS,,OS(=O)(=O)c1ccc2c(c1)C(CCC2C)CCCCCCC,"InChI=1S/C18H28O3S/c1-3-4-5-6-7-8-15-10-9-14(2)17-12-11-16(13-18(15)17)22(19,20)21/h11-15H,3-10H2,1-2H3,(H,19,20,21)",HLOWFOZRIFTRAW-UHFFFAOYSA-N,C18H28O3S,324.1759
+-1,C13-DATS,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCCCCC)C,"InChI=1S/C19H30O3S/c1-3-4-5-6-7-8-9-16-11-10-15(2)19-14-17(23(20,21)22)12-13-18(16)19/h12-16H,3-11H2,1-2H3,(H,20,21,22)",DVDPDFIXIQGHCK-UHFFFAOYSA-N,C19H30O3S,338.1916
+-1,C14-DATS,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCC)CCCCCCC,"InChI=1S/C20H32O3S/c1-3-5-6-7-8-10-17-12-11-16(9-4-2)19-14-13-18(15-20(17)19)24(21,22)23/h13-17H,3-12H2,1-2H3,(H,21,22,23)",NFOILCDJXFDDOJ-UHFFFAOYSA-N,C20H32O3S,352.2072
+-1,C15-DATS,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCCCCC)CCC,"InChI=1S/C21H34O3S/c1-3-5-6-7-8-9-11-18-13-12-17(10-4-2)21-16-19(25(22,23)24)14-15-20(18)21/h14-18H,3-13H2,1-2H3,(H,22,23,24)",KMIIEIPAFHPFND-UHFFFAOYSA-N,C21H34O3S,366.2229
+-1,C16-DATS,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCCCC)CCCCC,"InChI=1S/C22H36O3S/c1-3-5-7-8-10-12-18-13-14-19(11-9-6-4-2)22-17-20(26(23,24)25)15-16-21(18)22/h15-19H,3-14H2,1-2H3,(H,23,24,25)",NSSHWUGJTKRXNB-UHFFFAOYSA-N,C22H36O3S,380.2385
+-1,C17-DATS,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCCCCC)CCCCC,"InChI=1S/C23H38O3S/c1-3-5-7-8-9-11-13-19-14-15-20(12-10-6-4-2)23-18-21(27(24,25)26)16-17-22(19)23/h16-20H,3-15H2,1-2H3,(H,24,25,26)",WQFPXPQIUGXMCJ-UHFFFAOYSA-N,C23H38O3S,394.2542
+-1,C18-DATS,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCCCCC)CCCCCC,"InChI=1S/C24H40O3S/c1-3-5-7-9-10-12-13-20-15-16-21(14-11-8-6-4-2)24-19-22(28(25,26)27)17-18-23(20)24/h17-21H,3-16H2,1-2H3,(H,25,26,27)",OMWNLIPXMZVLSV-UHFFFAOYSA-N,C24H40O3S,408.2698
+-1,C19-DATS,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCCCCC)CCCCCCC,"InChI=1S/C25H42O3S/c1-3-5-7-9-11-13-14-21-16-17-22(15-12-10-8-6-4-2)25-20-23(29(26,27)28)18-19-24(21)25/h18-22H,3-17H2,1-2H3,(H,26,27,28)",SATGBNLTXNKXPQ-UHFFFAOYSA-N,C25H42O3S,422.2855
+-1,STA-2C,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CC(=O)O)C,"InChI=1S/C13H16O5S/c1-8-2-3-9(6-13(14)15)11-5-4-10(7-12(8)11)19(16,17)18/h4-5,7-9H,2-3,6H2,1H3,(H,14,15)(H,16,17,18)",YAYKASZBTYBOKK-UHFFFAOYSA-N,C13H16O5S,284.0718
+-1,STA-3C,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CC(=O)O)CC,"InChI=1S/C14H18O5S/c1-2-9-3-4-10(7-14(15)16)12-6-5-11(8-13(9)12)20(17,18)19/h5-6,8-10H,2-4,7H2,1H3,(H,15,16)(H,17,18,19)",SFYYMRZZQXITOX-UHFFFAOYSA-N,C14H18O5S,298.0875
+-1,STA-4C,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCC(=O)O)C,"InChI=1S/C15H20O5S/c1-10-5-6-11(3-2-4-15(16)17)13-8-7-12(9-14(10)13)21(18,19)20/h7-11H,2-6H2,1H3,(H,16,17)(H,18,19,20)",HFAMWNAXSCOTRZ-UHFFFAOYSA-N,C15H20O5S,312.1031
+-1,STA-5C,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCC(=O)O)C,"InChI=1S/C16H22O5S/c1-11-6-7-12(4-2-3-5-16(17)18)14-9-8-13(10-15(11)14)22(19,20)21/h8-12H,2-7H2,1H3,(H,17,18)(H,19,20,21)",SSIXZERVHKYXKK-UHFFFAOYSA-N,C16H22O5S,326.1188
+-1,STA-6C,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCCC(=O)O)C,"InChI=1S/C17H24O5S/c1-12-7-8-13(5-3-2-4-6-17(18)19)15-10-9-14(11-16(12)15)23(20,21)22/h9-13H,2-8H2,1H3,(H,18,19)(H,20,21,22)",MSXMPQQFLXAOLD-UHFFFAOYSA-N,C17H24O5S,340.1344
+-1,STA-7C,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCCCC(=O)O)C,"InChI=1S/C18H26O5S/c1-13-8-9-14(6-4-2-3-5-7-18(19)20)16-11-10-15(12-17(13)16)24(21,22)23/h10-14H,2-9H2,1H3,(H,19,20)(H,21,22,23)",PLNKPQBXRHHDAP-UHFFFAOYSA-N,C18H26O5S,354.1501
+-1,STA-8C,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCCCCC(=O)O)C,"InChI=1S/C19H28O5S/c1-14-9-10-15(7-5-3-2-4-6-8-19(20)21)17-12-11-16(13-18(14)17)25(22,23)24/h11-15H,2-10H2,1H3,(H,20,21)(H,22,23,24)",PHILMRCKDATNAY-UHFFFAOYSA-N,C19H28O5S,368.1657
+-1,STA-9C,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCCCCC(=O)O)CC,"InChI=1S/C20H30O5S/c1-2-15-10-11-16(8-6-4-3-5-7-9-20(21)22)18-13-12-17(14-19(15)18)26(23,24)25/h12-16H,2-11H2,1H3,(H,21,22)(H,23,24,25)",SXYXPSWQMIAWQQ-UHFFFAOYSA-N,C20H30O5S,382.1814
+-1,STA-10C,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCC(=O)O)CCCCCC,"InChI=1S/C21H32O5S/c1-2-3-4-5-8-17-12-11-16(9-6-7-10-21(22)23)19-14-13-18(15-20(17)19)27(24,25)26/h13-17H,2-12H2,1H3,(H,22,23)(H,24,25,26)",BRDFAMGDNFULLL-UHFFFAOYSA-N,C21H32O5S,396.197
+-1,STA-11C,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCCC(=O)O)CCCCCC,"InChI=1S/C22H34O5S/c1-2-3-4-6-10-18-13-12-17(9-7-5-8-11-22(23)24)20-15-14-19(16-21(18)20)28(25,26)27/h14-18H,2-13H2,1H3,(H,23,24)(H,25,26,27)",VBRFBUFJXGASGQ-UHFFFAOYSA-N,C22H34O5S,410.2127
+-1,STA-12C,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCCCC(=O)O)CCCCCC,"InChI=1S/C23H36O5S/c1-2-3-4-7-11-19-14-13-18(10-8-5-6-9-12-23(24)25)21-16-15-20(17-22(19)21)29(26,27)28/h15-19H,2-14H2,1H3,(H,24,25)(H,26,27,28)",FTIHSSALIIRLBS-UHFFFAOYSA-N,C23H36O5S,424.2283
+-1,STA-2DC,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CC(=O)O)CC(=O)O,"InChI=1S/C14H16O7S/c15-13(16)5-8-1-2-9(6-14(17)18)12-7-10(22(19,20)21)3-4-11(8)12/h3-4,7-9H,1-2,5-6H2,(H,15,16)(H,17,18)(H,19,20,21)",DJKOSZSOIYIRRS-UHFFFAOYSA-N,C14H16O7S,328.0617
+-1,STA-3DC,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CC(=O)O)CCC(=O)O,"InChI=1S/C15H18O7S/c16-14(17)6-3-9-1-2-10(7-15(18)19)12-5-4-11(8-13(9)12)23(20,21)22/h4-5,8-10H,1-3,6-7H2,(H,16,17)(H,18,19)(H,20,21,22)",DTPSWYPGRJLURN-UHFFFAOYSA-N,C15H18O7S,342.0773
+-1,STA-4DC,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CC(=O)O)CCCC(=O)O,"InChI=1S/C16H20O7S/c17-15(18)3-1-2-10-4-5-11(8-16(19)20)13-7-6-12(9-14(10)13)24(21,22)23/h6-7,9-11H,1-5,8H2,(H,17,18)(H,19,20)(H,21,22,23)",YZQCYNFIFXLXEW-UHFFFAOYSA-N,C16H20O7S,356.093
+-1,STA-5DC,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCC(=O)O)CCCC(=O)O,"InChI=1S/C17H22O7S/c18-16(19)3-1-2-11-4-5-12(6-9-17(20)21)14-8-7-13(10-15(11)14)25(22,23)24/h7-8,10-12H,1-6,9H2,(H,18,19)(H,20,21)(H,22,23,24)",ZUYLWQWQUFYPKJ-UHFFFAOYSA-N,C17H22O7S,370.1086
+-1,STA-6DC,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCC(=O)O)CCCCC(=O)O,"InChI=1S/C18H24O7S/c19-17(20)4-2-1-3-12-5-6-13(7-10-18(21)22)15-9-8-14(11-16(12)15)26(23,24)25/h8-9,11-13H,1-7,10H2,(H,19,20)(H,21,22)(H,23,24,25)",NGSXGKJEAWECPW-UHFFFAOYSA-N,C18H24O7S,384.1243
+-1,STA-7DC,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCC(=O)O)CCCCCC(=O)O,"InChI=1S/C19H26O7S/c20-18(21)5-3-1-2-4-13-6-7-14(8-11-19(22)23)16-10-9-15(12-17(13)16)27(24,25)26/h9-10,12-14H,1-8,11H2,(H,20,21)(H,22,23)(H,24,25,26)",ZYBOUKMOUZCFSE-UHFFFAOYSA-N,C19H26O7S,398.1399
+-1,STA-8DC,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCC(=O)O)CCCCCCC(=O)O,"InChI=1S/C20H28O7S/c21-19(22)6-4-2-1-3-5-14-7-8-15(9-12-20(23)24)17-11-10-16(13-18(14)17)28(25,26)27/h10-11,13-15H,1-9,12H2,(H,21,22)(H,23,24)(H,25,26,27)",NXFKWPHXJAJBJL-UHFFFAOYSA-N,C20H28O7S,412.1556
+-1,STA-9DC,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCC(=O)O)CCCCCCCC(=O)O,"InChI=1S/C21H30O7S/c22-20(23)7-5-3-1-2-4-6-15-8-9-16(10-13-21(24)25)18-12-11-17(14-19(15)18)29(26,27)28/h11-12,14-16H,1-10,13H2,(H,22,23)(H,24,25)(H,26,27,28)",QALHLGWPOKDSAX-UHFFFAOYSA-N,C21H30O7S,426.1712
+-1,STA-10DC,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCCCCCC(=O)O)CCC(=O)O,"InChI=1S/C22H32O7S/c23-21(24)8-6-4-2-1-3-5-7-16-9-10-17(11-14-22(25)26)20-15-18(30(27,28)29)12-13-19(16)20/h12-13,15-17H,1-11,14H2,(H,23,24)(H,25,26)(H,27,28,29)",WPAOHAOWYFRHKK-UHFFFAOYSA-N,C22H32O7S,440.1869
+-1,STA-11DC,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCCCCC(=O)O)CCCCC(=O)O,"InChI=1S/C23H34O7S/c24-22(25)10-5-3-1-2-4-8-17-12-13-18(9-6-7-11-23(26)27)21-16-19(31(28,29)30)14-15-20(17)21/h14-18H,1-13H2,(H,24,25)(H,26,27)(H,28,29,30)",YTVWBEMKDUKMAR-UHFFFAOYSA-N,C23H34O7S,454.2025
+-1,STA-12DC,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCCCCCC(=O)O)CCCCC(=O)O,"InChI=1S/C24H36O7S/c25-23(26)11-6-4-2-1-3-5-9-18-13-14-19(10-7-8-12-24(27)28)22-17-20(32(29,30)31)15-16-21(18)22/h15-19H,1-14H2,(H,25,26)(H,27,28)(H,29,30,31)",TXZJUAOIWAHRMT-UHFFFAOYSA-N,C24H36O7S,468.2182
+-1,STA-13DC,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCCCCC(=O)O)CCCCCCC(=O)O,"InChI=1S/C25H38O7S/c26-24(27)12-8-3-1-2-6-10-19-14-15-20(11-7-4-5-9-13-25(28)29)23-18-21(33(30,31)32)16-17-22(19)23/h16-20H,1-15H2,(H,26,27)(H,28,29)(H,30,31,32)",PMBZAKTZWJTIEF-UHFFFAOYSA-N,C25H38O7S,482.2338
+-1,STA-14DC,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCCCCCC(=O)O)CCCCCCC(=O)O,"InChI=1S/C26H40O7S/c27-25(28)13-9-4-2-1-3-7-11-20-15-16-21(12-8-5-6-10-14-26(29)30)24-19-22(34(31,32)33)17-18-23(20)24/h17-21H,1-16H2,(H,27,28)(H,29,30)(H,31,32,33)",QQDNWFHFSCIGAC-UHFFFAOYSA-N,C26H40O7S,496.2495
+-1,STA-15DC,,OS(=O)(=O)c1ccc2c(c1)C(CCC2CCCCCCCCC(=O)O)CCCCCCCC(=O)O,"InChI=1S/C27H42O7S/c28-26(29)14-10-6-2-1-4-8-12-21-16-17-22(13-9-5-3-7-11-15-27(30)31)25-20-23(35(32,33)34)18-19-24(21)25/h18-22H,1-17H2,(H,28,29)(H,30,31)(H,32,33,34)",WXQPJKPAJUVDCJ-UHFFFAOYSA-N,C27H42O7S,510.2651
+-1,C12-AS,,O=S(=O)(O)OCCCCCCCCCCCC,"InChI=1S/C12H26O4S/c1-2-3-4-5-6-7-8-9-10-11-12-16-17(13,14)15/h2-12H2,1H3,(H,13,14,15)",MOTZDAYCYVMXPC-UHFFFAOYSA-N,C12H26O4S,266.1552
+-1,C13-AS,,O=S(=O)(O)OCCCCCCCCCCCCC,"InChI=1S/C13H28O4S/c1-2-3-4-5-6-7-8-9-10-11-12-13-17-18(14,15)16/h2-13H2,1H3,(H,14,15,16)",QTUIJRIDZOSXHJ-UHFFFAOYSA-N,C13H28O4S,280.1708
+-1,C14-AS,,O=S(=O)(O)OCCCCCCCCCCCCCC,"InChI=1S/C14H30O4S/c1-2-3-4-5-6-7-8-9-10-11-12-13-14-18-19(15,16)17/h2-14H2,1H3,(H,15,16,17)",URLJMZWTXZTZRR-UHFFFAOYSA-N,C14H30O4S,294.1865
+-1,C15-AS,,O=S(=O)(O)OCCCCCCCCCCCCCCC,"InChI=1S/C15H32O4S/c1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-19-20(16,17)18/h2-15H2,1H3,(H,16,17,18)",COUMKTRLCGRAAA-UHFFFAOYSA-N,C15H32O4S,308.2021
+-1,C16-AS,,O=S(=O)(O)OCCCCCCCCCCCCCCCC,"InChI=1S/C16H34O4S/c1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-20-21(17,18)19/h2-16H2,1H3,(H,17,18,19)",LPTIRUACFKQDHZ-UHFFFAOYSA-N,C16H34O4S,322.2178
+2,C12-AE2S,CCCCCCCCCC,O=S(O)(=O)OCCOCCOCCCCCCCCCCCC,"InChI=1S/C16H34O6S/c1-2-3-4-5-6-7-8-9-10-11-12-20-13-14-21-15-16-22-23(17,18)19/h2-16H2,1H3,(H,17,18,19)",CJWXGVNXFJTQFT-UHFFFAOYSA-N,C16H34O6S,354.2076
+2,C12-AE3S,CCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCCCCCCCCCCC,"InChI=1S/C18H38O7S/c1-2-3-4-5-6-7-8-9-10-11-12-22-13-14-23-15-16-24-17-18-25-26(19,20)21/h2-18H2,1H3,(H,19,20,21)",SBSKZXOUCHIBBW-UHFFFAOYSA-N,C18H38O7S,398.2338
+2,C12-AE4S,CCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCOCCCCCCCCCCCC,"InChI=1S/C20H42O8S/c1-2-3-4-5-6-7-8-9-10-11-12-24-13-14-25-15-16-26-17-18-27-19-20-28-29(21,22)23/h2-20H2,1H3,(H,21,22,23)",ACSZGWVXTPNMNT-UHFFFAOYSA-N,C20H42O8S,442.26
+2,C12-AE5S,CCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCOCCOCCCCCCCCCCCC,"InChI=1S/C22H46O9S/c1-2-3-4-5-6-7-8-9-10-11-12-26-13-14-27-15-16-28-17-18-29-19-20-30-21-22-31-32(23,24)25/h2-22H2,1H3,(H,23,24,25)",PGQXGWUGIBIDNM-UHFFFAOYSA-N,C22H46O9S,486.2863
+2,C12-AE6S,CCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCOCCOCCOCCCCCCCCCCCC,"InChI=1S/C24H50O10S/c1-2-3-4-5-6-7-8-9-10-11-12-28-13-14-29-15-16-30-17-18-31-19-20-32-21-22-33-23-24-34-35(25,26)27/h2-24H2,1H3,(H,25,26,27)",BNYUUDPIQXXNHL-UHFFFAOYSA-N,C24H50O10S,530.3125
+2,C12-AE7S,CCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCOCCOCCOCCOCCCCCCCCCCCC,"InChI=1S/C26H54O11S/c1-2-3-4-5-6-7-8-9-10-11-12-30-13-14-31-15-16-32-17-18-33-19-20-34-21-22-35-23-24-36-25-26-37-38(27,28)29/h2-26H2,1H3,(H,27,28,29)",FZACGOAIMANYDC-UHFFFAOYSA-N,C26H54O11S,574.3387
+2,C12-AE8S,CCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCOCCOCCOCCOCCOCCCCCCCCCCCC,"InChI=1S/C28H58O12S/c1-2-3-4-5-6-7-8-9-10-11-12-32-13-14-33-15-16-34-17-18-35-19-20-36-21-22-37-23-24-38-25-26-39-27-28-40-41(29,30)31/h2-28H2,1H3,(H,29,30,31)",BHBLZGIVCIYBCP-UHFFFAOYSA-N,C28H58O12S,618.3649
+2,C12-AE9S,CCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCCCCCCCCCCC,"InChI=1S/C30H62O13S/c1-2-3-4-5-6-7-8-9-10-11-12-34-13-14-35-15-16-36-17-18-37-19-20-38-21-22-39-23-24-40-25-26-41-27-28-42-29-30-43-44(31,32)33/h2-30H2,1H3,(H,31,32,33)",RFLFWPNQPFERGY-UHFFFAOYSA-N,C30H62O13S,662.3911
+2,C12-AE10S,CCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCCCCCCCCCCC,"InChI=1S/C32H66O14S/c1-2-3-4-5-6-7-8-9-10-11-12-36-13-14-37-15-16-38-17-18-39-19-20-40-21-22-41-23-24-42-25-26-43-27-28-44-29-30-45-31-32-46-47(33,34)35/h2-32H2,1H3,(H,33,34,35)",ISWNVBHHPQYWKV-UHFFFAOYSA-N,C32H66O14S,706.4173
+2,C12-AE11S,CCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCCCCCCCCCCC,"InChI=1S/C34H70O15S/c1-2-3-4-5-6-7-8-9-10-11-12-38-13-14-39-15-16-40-17-18-41-19-20-42-21-22-43-23-24-44-25-26-45-27-28-46-29-30-47-31-32-48-33-34-49-50(35,36)37/h2-34H2,1H3,(H,35,36,37)",LDOQTQSGBCHOLS-UHFFFAOYSA-N,C34H70O15S,750.4435
+2,C12-AE12S,CCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCCCCCCCCCCC,"InChI=1S/C36H74O16S/c1-2-3-4-5-6-7-8-9-10-11-12-40-13-14-41-15-16-42-17-18-43-19-20-44-21-22-45-23-24-46-25-26-47-27-28-48-29-30-49-31-32-50-33-34-51-35-36-52-53(37,38)39/h2-36H2,1H3,(H,37,38,39)",KORVYZBRZQALBX-UHFFFAOYSA-N,C36H74O16S,794.4698
+3,C13-AE2S,CCCCCCCCCCC,O=S(O)(=O)OCCOCCOCCCCCCCCCCCCC,"InChI=1S/C17H36O6S/c1-2-3-4-5-6-7-8-9-10-11-12-13-21-14-15-22-16-17-23-24(18,19)20/h2-17H2,1H3,(H,18,19,20)",GPHSQVBETPHGQE-UHFFFAOYSA-N,C17H36O6S,368.2233
+3,C13-AE3S,CCCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCCCCCCCCCCCC,"InChI=1S/C19H40O7S/c1-2-3-4-5-6-7-8-9-10-11-12-13-23-14-15-24-16-17-25-18-19-26-27(20,21)22/h2-19H2,1H3,(H,20,21,22)",GLTCJAJTWUOWFS-UHFFFAOYSA-N,C19H40O7S,412.2495
+3,C13-AE4S,CCCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCOCCCCCCCCCCCCC,"InChI=1S/C21H44O8S/c1-2-3-4-5-6-7-8-9-10-11-12-13-25-14-15-26-16-17-27-18-19-28-20-21-29-30(22,23)24/h2-21H2,1H3,(H,22,23,24)",WNCBVFJYAHNHDS-UHFFFAOYSA-N,C21H44O8S,456.2757
+3,C13-AE5S,CCCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCOCCOCCCCCCCCCCCCC,"InChI=1S/C23H48O9S/c1-2-3-4-5-6-7-8-9-10-11-12-13-27-14-15-28-16-17-29-18-19-30-20-21-31-22-23-32-33(24,25)26/h2-23H2,1H3,(H,24,25,26)",ZPYMSTPUPJZMMW-UHFFFAOYSA-N,C23H48O9S,500.3019
+3,C13-AE6S,CCCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCOCCOCCOCCCCCCCCCCCCC,"InChI=1S/C25H52O10S/c1-2-3-4-5-6-7-8-9-10-11-12-13-29-14-15-30-16-17-31-18-19-32-20-21-33-22-23-34-24-25-35-36(26,27)28/h2-25H2,1H3,(H,26,27,28)",HFJHRIIHBNHCLJ-UHFFFAOYSA-N,C25H52O10S,544.3281
+3,C13-AE7S,CCCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCOCCOCCOCCOCCCCCCCCCCCCC,"InChI=1S/C27H56O11S/c1-2-3-4-5-6-7-8-9-10-11-12-13-31-14-15-32-16-17-33-18-19-34-20-21-35-22-23-36-24-25-37-26-27-38-39(28,29)30/h2-27H2,1H3,(H,28,29,30)",YGKSAWGEOSNFCW-UHFFFAOYSA-N,C27H56O11S,588.3543
+3,C13-AE8S,CCCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCOCCOCCOCCOCCOCCCCCCCCCCCCC,"InChI=1S/C29H60O12S/c1-2-3-4-5-6-7-8-9-10-11-12-13-33-14-15-34-16-17-35-18-19-36-20-21-37-22-23-38-24-25-39-26-27-40-28-29-41-42(30,31)32/h2-29H2,1H3,(H,30,31,32)",VMVQDUSWHRVLBE-UHFFFAOYSA-N,C29H60O12S,632.3805
+3,C13-AE9S,CCCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCCCCCCCCCCCC,"InChI=1S/C31H64O13S/c1-2-3-4-5-6-7-8-9-10-11-12-13-35-14-15-36-16-17-37-18-19-38-20-21-39-22-23-40-24-25-41-26-27-42-28-29-43-30-31-44-45(32,33)34/h2-31H2,1H3,(H,32,33,34)",CBIMCCAGIVDGKB-UHFFFAOYSA-N,C31H64O13S,676.4068
+3,C13-AE10S,CCCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCCCCCCCCCCCC,"InChI=1S/C33H68O14S/c1-2-3-4-5-6-7-8-9-10-11-12-13-37-14-15-38-16-17-39-18-19-40-20-21-41-22-23-42-24-25-43-26-27-44-28-29-45-30-31-46-32-33-47-48(34,35)36/h2-33H2,1H3,(H,34,35,36)",JRJGKDSTAKYQMA-UHFFFAOYSA-N,C33H68O14S,720.433
+3,C13-AE11S,CCCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCCCCCCCCCCCC,"InChI=1S/C35H72O15S/c1-2-3-4-5-6-7-8-9-10-11-12-13-39-14-15-40-16-17-41-18-19-42-20-21-43-22-23-44-24-25-45-26-27-46-28-29-47-30-31-48-32-33-49-34-35-50-51(36,37)38/h2-35H2,1H3,(H,36,37,38)",CQZOPQGONJYKPA-UHFFFAOYSA-N,C35H72O15S,764.4592
+3,C13-AE12S,CCCCCCCCCCC,O=S(O)(=O)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCCCCCCCCCCCC,"InChI=1S/C37H76O16S/c1-2-3-4-5-6-7-8-9-10-11-12-13-41-14-15-42-16-17-43-18-19-44-20-21-45-22-23-46-24-25-47-26-27-48-28-29-49-30-31-50-32-33-51-34-35-52-36-37-53-54(38,39)40/h2-37H2,1H3,(H,38,39,40)",ISRDUHOCGAQXDD-UHFFFAOYSA-N,C37H76O16S,808.4854
+-1,C10-SAS,,O=S(O)(=O)C(CCCCC)CCCC,"InChI=1S/C10H22O3S/c1-3-5-7-9-10(8-6-4-2)14(11,12)13/h10H,3-9H2,1-2H3,(H,11,12,13)",CLHWZDBKYXSFFK-UHFFFAOYSA-N,C10H22O3S,222.129
+-1,C11-SAS,,O=S(O)(=O)C(CCCCCC)CCCC,"InChI=1S/C11H24O3S/c1-3-5-7-8-10-11(9-6-4-2)15(12,13)14/h11H,3-10H2,1-2H3,(H,12,13,14)",IWZVUKJVPRJMCV-UHFFFAOYSA-N,C11H24O3S,236.1446
+-1,C12-SAS,,O=S(O)(=O)C(CCCCCCC)CCCC,"InChI=1S/C12H26O3S/c1-3-5-7-8-9-11-12(10-6-4-2)16(13,14)15/h12H,3-11H2,1-2H3,(H,13,14,15)",BSQQGKMAIODZDZ-UHFFFAOYSA-N,C12H26O3S,250.1603
+-1,C13-SAS,,O=S(O)(=O)C(CCCCC)CCCCCCC,"InChI=1S/C13H28O3S/c1-3-5-7-8-10-12-13(17(14,15)16)11-9-6-4-2/h13H,3-12H2,1-2H3,(H,14,15,16)",KTVQXHPSFBSSTJ-UHFFFAOYSA-N,C13H28O3S,264.1759
+-1,C14-SAS,,O=S(O)(=O)C(CCCCCCCCC)CCCC,"InChI=1S/C14H30O3S/c1-3-5-7-8-9-10-11-13-14(12-6-4-2)18(15,16)17/h14H,3-13H2,1-2H3,(H,15,16,17)",BTPXRGIPAXXPNB-UHFFFAOYSA-N,C14H30O3S,278.1916
+-1,C15-SAS,,O=S(O)(=O)C(CCCCCCCCCC)CCCC,"InChI=1S/C15H32O3S/c1-3-5-7-8-9-10-11-12-14-15(13-6-4-2)19(16,17)18/h15H,3-14H2,1-2H3,(H,16,17,18)",PSHQOLNJGLLTDT-UHFFFAOYSA-N,C15H32O3S,292.2072
+-1,C16-SAS,,O=S(O)(=O)C(CCCCC)CCCCCCCCCC,"InChI=1S/C16H34O3S/c1-3-5-7-8-9-10-11-13-15-16(20(17,18)19)14-12-6-4-2/h16H,3-15H2,1-2H3,(H,17,18,19)",QVERVCKBMFECAK-UHFFFAOYSA-N,C16H34O3S,306.2229
+-1,C17-SAS,,O=S(O)(=O)C(CCCCCC)CCCCCCCCCC,"InChI=1S/C17H36O3S/c1-3-5-7-9-10-11-12-14-16-17(21(18,19)20)15-13-8-6-4-2/h17H,3-16H2,1-2H3,(H,18,19,20)",YRQQPWVBSQEBPW-UHFFFAOYSA-N,C17H36O3S,320.2385
+-1,C18-SAS,,O=S(O)(=O)C(CCCCCCC)CCCCCCCCCC,"InChI=1S/C18H38O3S/c1-3-5-7-9-10-11-13-15-17-18(22(19,20)21)16-14-12-8-6-4-2/h18H,3-17H2,1-2H3,(H,19,20,21)",YOXNJPLWSLWLQI-UHFFFAOYSA-N,C18H38O3S,334.2542
+-1,C19-SAS,,O=S(O)(=O)C(CCCCCCCC)CCCCCCCCCC,"InChI=1S/C19H40O3S/c1-3-5-7-9-11-12-14-16-18-19(23(20,21)22)17-15-13-10-8-6-4-2/h19H,3-18H2,1-2H3,(H,20,21,22)",YXWDSEJGFLEXSH-UHFFFAOYSA-N,C19H40O3S,348.2698
+-1,C20-SAS,,O=S(O)(=O)C(CCCCCCCCCC)CCCCCCCCC,"InChI=1S/C20H42O3S/c1-3-5-7-9-11-13-15-17-19-20(24(21,22)23)18-16-14-12-10-8-6-4-2/h20H,3-19H2,1-2H3,(H,21,22,23)",SDWPANLVMNASEQ-UHFFFAOYSA-N,C20H42O3S,362.2855
+-1,C21-SAS,,O=S(O)(=O)C(CCCCCCCCCC)CCCCCCCCCC,"InChI=1S/C21H44O3S/c1-3-5-7-9-11-13-15-17-19-21(25(22,23)24)20-18-16-14-12-10-8-6-4-2/h21H,3-20H2,1-2H3,(H,22,23,24)",AQXMUZIEAPVCJB-UHFFFAOYSA-N,C21H44O3S,376.3011
+0,C10-AEO-2,CCCCCCCC,OCCOCCOCCCCCCCCCC,"InChI=1S/C14H30O3/c1-2-3-4-5-6-7-8-9-11-16-13-14-17-12-10-15/h15H,2-14H2,1H3",UVNSFSOKRSZVEZ-UHFFFAOYSA-N,C14H30O3,246.2195
+1,C11-AEO-2,CCCCCCCCC,OCCOCCOCCCCCCCCCCC,"InChI=1S/C15H32O3/c1-2-3-4-5-6-7-8-9-10-12-17-14-15-18-13-11-16/h16H,2-15H2,1H3",JHLNZBMSRRDBRC-UHFFFAOYSA-N,C15H32O3,260.2351
+2,C12-AEO-2,CCCCCCCCCC,OCCOCCOCCCCCCCCCCCC,"InChI=1S/C16H34O3/c1-2-3-4-5-6-7-8-9-10-11-13-18-15-16-19-14-12-17/h17H,2-16H2,1H3",AZLWQVJVINEILY-UHFFFAOYSA-N,C16H34O3,274.2508
+3,C13-AEO-2,CCCCCCCCCCC,OCCOCCOCCCCCCCCCCCCC,"InChI=1S/C17H36O3/c1-2-3-4-5-6-7-8-9-10-11-12-14-19-16-17-20-15-13-18/h18H,2-17H2,1H3",RTRMBXZHMWADJB-UHFFFAOYSA-N,C17H36O3,288.2664
+0,C10-AEO-3,CCCCCCCC,OCCOCCOCCOCCCCCCCCCC,"InChI=1S/C16H34O4/c1-2-3-4-5-6-7-8-9-11-18-13-15-20-16-14-19-12-10-17/h17H,2-16H2,1H3",UKODLHVFJRCQME-UHFFFAOYSA-N,C16H34O4,290.2457
+1,C11-AEO-3,CCCCCCCCC,OCCOCCOCCOCCCCCCCCCCC,"InChI=1S/C17H36O4/c1-2-3-4-5-6-7-8-9-10-12-19-14-16-21-17-15-20-13-11-18/h18H,2-17H2,1H3",ASULYNFXTCGEAN-UHFFFAOYSA-N,C17H36O4,304.2614
+2,C12-AEO-3,CCCCCCCCCC,OCCOCCOCCOCCCCCCCCCCCC,"InChI=1S/C18H38O4/c1-2-3-4-5-6-7-8-9-10-11-13-20-15-17-22-18-16-21-14-12-19/h19H,2-18H2,1H3",FKMHSNTVILORFA-UHFFFAOYSA-N,C18H38O4,318.277
+3,C13-AEO-3,CCCCCCCCCCC,OCCOCCOCCOCCCCCCCCCCCCC,"InChI=1S/C19H40O4/c1-2-3-4-5-6-7-8-9-10-11-12-14-21-16-18-23-19-17-22-15-13-20/h20H,2-19H2,1H3",KLFVDTRVIFNWIH-UHFFFAOYSA-N,C19H40O4,332.2927
+0,C10-AEO-4,CCCCCCCC,OCCOCCOCCOCCOCCCCCCCCCC,"InChI=1S/C18H38O5/c1-2-3-4-5-6-7-8-9-11-20-13-15-22-17-18-23-16-14-21-12-10-19/h19H,2-18H2,1H3",ASMWIUUCZFNLHL-UHFFFAOYSA-N,C18H38O5,334.2719
+1,C11-AEO-4,CCCCCCCCC,OCCOCCOCCOCCOCCCCCCCCCCC,"InChI=1S/C19H40O5/c1-2-3-4-5-6-7-8-9-10-12-21-14-16-23-18-19-24-17-15-22-13-11-20/h20H,2-19H2,1H3",MGAAPFMMNKLGSQ-UHFFFAOYSA-N,C19H40O5,348.2876
+2,C12-AEO-4,CCCCCCCCCC,OCCOCCOCCOCCOCCCCCCCCCCCC,"InChI=1S/C20H42O5/c1-2-3-4-5-6-7-8-9-10-11-13-22-15-17-24-19-20-25-18-16-23-14-12-21/h21H,2-20H2,1H3",WPMWEFXCIYCJSA-UHFFFAOYSA-N,C20H42O5,362.3032
+3,C13-AEO-4,CCCCCCCCCCC,OCCOCCOCCOCCOCCCCCCCCCCCCC,"InChI=1S/C21H44O5/c1-2-3-4-5-6-7-8-9-10-11-12-14-23-16-18-25-20-21-26-19-17-24-15-13-22/h22H,2-21H2,1H3",XGJLRCKXPUPYKH-UHFFFAOYSA-N,C21H44O5,376.3189
+0,C10-AEO-10,CCCCCCCC,OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCCCCCCCCC,"InChI=1S/C30H62O11/c1-2-3-4-5-6-7-8-9-11-32-13-15-34-17-19-36-21-23-38-25-27-40-29-30-41-28-26-39-24-22-37-20-18-35-16-14-33-12-10-31/h31H,2-30H2,1H3",DJPHBXSFUOFPSJ-UHFFFAOYSA-N,C30H62O11,598.4292
+1,C11-AEO-10,CCCCCCCCC,OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCCCCCCCCCC,"InChI=1S/C31H64O11/c1-2-3-4-5-6-7-8-9-10-12-33-14-16-35-18-20-37-22-24-39-26-28-41-30-31-42-29-27-40-25-23-38-21-19-36-17-15-34-13-11-32/h32H,2-31H2,1H3",FGOLUKGSPRJRJO-UHFFFAOYSA-N,C31H64O11,612.4449
+2,C12-AEO-10,CCCCCCCCCC,OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCCCCCCCCCCC,"InChI=1S/C32H66O11/c1-2-3-4-5-6-7-8-9-10-11-13-34-15-17-36-19-21-38-23-25-40-27-29-42-31-32-43-30-28-41-26-24-39-22-20-37-18-16-35-14-12-33/h33H,2-32H2,1H3",KOMQWDINDMFMPD-UHFFFAOYSA-N,C32H66O11,626.4605
+3,C13-AEO-10,CCCCCCCCCCC,OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCCCCCCCCCCCC,"InChI=1S/C33H68O11/c1-2-3-4-5-6-7-8-9-10-11-12-14-35-16-18-37-20-22-39-24-26-41-28-30-43-32-33-44-31-29-42-27-25-40-23-21-38-19-17-36-15-13-34/h34H,2-33H2,1H3",JPEAHLRGZPDLOT-UHFFFAOYSA-N,C33H68O11,640.4762
+-1,C14-AEO-10,CCCCCCCCCCCC,OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCCCCCCCCCCCCC,"InChI=1S/C34H70O11/c1-2-3-4-5-6-7-8-9-10-11-12-13-15-36-17-19-38-21-23-40-25-27-42-29-31-44-33-34-45-32-30-43-28-26-41-24-22-39-20-18-37-16-14-35/h35H,2-34H2,1H3",FJGDXIUISWQNSF-UHFFFAOYSA-N,C34H70O11,654.4918
+-1,C7DEA,,O=C(CCCCCCC)N(CCO)CCO,"InChI=1S/C12H25NO3/c1-2-3-4-5-6-7-12(16)13(8-10-14)9-11-15/h14-15H,2-11H2,1H3",FZQAYFWUOCXLKJ-UHFFFAOYSA-N,C12H25NO3,231.1834
+-1,C9DEA,,O=C(CCCCCCCCC)N(CCO)CCO,"InChI=1S/C14H29NO3/c1-2-3-4-5-6-7-8-9-14(18)15(10-12-16)11-13-17/h16-17H,2-13H2,1H3",BPXGKRUSMCVZAF-UHFFFAOYSA-N,C14H29NO3,259.2147
+-1,C11DEA,,O=C(CCCCCCCCCCC)N(CCO)CCO,"InChI=1S/C16H33NO3/c1-2-3-4-5-6-7-8-9-10-11-16(20)17(12-14-18)13-15-19/h18-19H,2-15H2,1H3",AOMUHOFOVNGZAN-UHFFFAOYSA-N,C16H33NO3,287.246
+-1,C13DEA,,O=C(CCCCCCCCCCCCC)N(CCO)CCO,"InChI=1S/C18H37NO3/c1-2-3-4-5-6-7-8-9-10-11-12-13-18(22)19(14-16-20)15-17-21/h20-21H,2-17H2,1H3",SKDZEPBJPGSFHS-UHFFFAOYSA-N,C18H37NO3,315.2773
+-1,C15DEA,,O=C(CCCCCCCCCCCCCCC)N(CCO)CCO,"InChI=1S/C20H41NO3/c1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-20(24)21(16-18-22)17-19-23/h22-23H,2-19H2,1H3",VJESJEJNMGVQLZ-UHFFFAOYSA-N,C20H41NO3,343.3086
+-1,C17DEA,,O=C(CCCCCCCCCCCCCCCCC)N(CCO)CCO,"InChI=1S/C22H45NO3/c1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-22(26)23(18-20-24)19-21-25/h24-25H,2-21H2,1H3",XGZOMURMPLSSKQ-UHFFFAOYSA-N,C22H45NO3,371.3399
+-1,NPEO1,,CCCCCCCCCc1ccc(cc1)OCCO,"InChI=1S/C17H28O2/c1-2-3-4-5-6-7-8-9-16-10-12-17(13-11-16)19-15-14-18/h10-13,18H,2-9,14-15H2,1H3",KUXGUCNZFCVULO-UHFFFAOYSA-N,C17H28O2,264.2089
+-1,NPEO2,,CCCCCCCCCc1ccc(cc1)OCCOCCO,"InChI=1S/C19H32O3/c1-2-3-4-5-6-7-8-9-18-10-12-19(13-11-18)22-17-16-21-15-14-20/h10-13,20H,2-9,14-17H2,1H3",BLXVTZPGEOGTGG-UHFFFAOYSA-N,C19H32O3,308.2351
+4,NPEO3,CCCCCCCCCc1ccccc1,CCCCCCCCCc1ccc(cc1)OCCOCCOCCO,"InChI=1S/C21H36O4/c1-2-3-4-5-6-7-8-9-20-10-12-21(13-11-20)25-19-18-24-17-16-23-15-14-22/h10-13,22H,2-9,14-19H2,1H3",ZIJRVWRFZGXKMY-UHFFFAOYSA-N,C21H36O4,352.2614
+4,NPEO4,CCCCCCCCCc1ccccc1,CCCCCCCCCc1ccc(cc1)OCCOCCOCCOCCO,"InChI=1S/C23H40O5/c1-2-3-4-5-6-7-8-9-22-10-12-23(13-11-22)28-21-20-27-19-18-26-17-16-25-15-14-24/h10-13,24H,2-9,14-21H2,1H3",UTXPMECBRCEYCI-UHFFFAOYSA-N,C23H40O5,396.2876
+4,NPEO5,CCCCCCCCCc1ccccc1,CCCCCCCCCc1ccc(cc1)OCCOCCOCCOCCOCCO,"InChI=1S/C25H44O6/c1-2-3-4-5-6-7-8-9-24-10-12-25(13-11-24)31-23-22-30-21-20-29-19-18-28-17-16-27-15-14-26/h10-13,26H,2-9,14-23H2,1H3",PITRRWWILGYENJ-UHFFFAOYSA-N,C25H44O6,440.3138
+4,NPEO6,CCCCCCCCCc1ccccc1,CCCCCCCCCc1ccc(cc1)OCCOCCOCCOCCOCCOCCO,"InChI=1S/C27H48O7/c1-2-3-4-5-6-7-8-9-26-10-12-27(13-11-26)34-25-24-33-23-22-32-21-20-31-19-18-30-17-16-29-15-14-28/h10-13,28H,2-9,14-25H2,1H3",CEWJCLBGTPZECP-UHFFFAOYSA-N,C27H48O7,484.34
+4,NPEO7,CCCCCCCCCc1ccccc1,CCCCCCCCCc1ccc(cc1)OCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C29H52O8/c1-2-3-4-5-6-7-8-9-28-10-12-29(13-11-28)37-27-26-36-25-24-35-23-22-34-21-20-33-19-18-32-17-16-31-15-14-30/h10-13,30H,2-9,14-27H2,1H3",ATBQNLZREVOGBO-UHFFFAOYSA-N,C29H52O8,528.3662
+4,NPEO8,CCCCCCCCCc1ccccc1,CCCCCCCCCc1ccc(cc1)OCCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C31H56O9/c1-2-3-4-5-6-7-8-9-30-10-12-31(13-11-30)40-29-28-39-27-26-38-25-24-37-23-22-36-21-20-35-19-18-34-17-16-33-15-14-32/h10-13,32H,2-9,14-29H2,1H3",XXPRRHYTDCWGRP-UHFFFAOYSA-N,C31H56O9,572.3924
+4,NPEO9,CCCCCCCCCc1ccccc1,CCCCCCCCCc1ccc(cc1)OCCOCCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C33H60O10/c1-2-3-4-5-6-7-8-9-32-10-12-33(13-11-32)43-31-30-42-29-28-41-27-26-40-25-24-39-23-22-38-21-20-37-19-18-36-17-16-35-15-14-34/h10-13,34H,2-9,14-31H2,1H3",FBWNMEQMRUMQSO-UHFFFAOYSA-N,C33H60O10,616.4186
+4,NPEO10,CCCCCCCCCc1ccccc1,CCCCCCCCCc1ccc(cc1)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C35H64O11/c1-2-3-4-5-6-7-8-9-34-10-12-35(13-11-34)46-33-32-45-31-30-44-29-28-43-27-26-42-25-24-41-23-22-40-21-20-39-19-18-38-17-16-37-15-14-36/h10-13,36H,2-9,14-33H2,1H3",CXIISRLRZRAKST-UHFFFAOYSA-N,C35H64O11,660.4449
+4,NPEO11,CCCCCCCCCc1ccccc1,CCCCCCCCCc1ccc(cc1)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C37H68O12/c1-2-3-4-5-6-7-8-9-36-10-12-37(13-11-36)49-35-34-48-33-32-47-31-30-46-29-28-45-27-26-44-25-24-43-23-22-42-21-20-41-19-18-40-17-16-39-15-14-38/h10-13,38H,2-9,14-35H2,1H3",YFTZKLGVTSRCMS-UHFFFAOYSA-N,C37H68O12,704.4711
+4,NPEO12,CCCCCCCCCc1ccccc1,CCCCCCCCCc1ccc(cc1)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C39H72O13/c1-2-3-4-5-6-7-8-9-38-10-12-39(13-11-38)52-37-36-51-35-34-50-33-32-49-31-30-48-29-28-47-27-26-46-25-24-45-23-22-44-21-20-43-19-18-42-17-16-41-15-14-40/h10-13,40H,2-9,14-37H2,1H3",WIHIUFRJMOAJFO-UHFFFAOYSA-N,C39H72O13,748.4973
+4,NPEO13,CCCCCCCCCc1ccccc1,CCCCCCCCCc1ccc(cc1)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C41H76O14/c1-2-3-4-5-6-7-8-9-40-10-12-41(13-11-40)55-39-38-54-37-36-53-35-34-52-33-32-51-31-30-50-29-28-49-27-26-48-25-24-47-23-22-46-21-20-45-19-18-44-17-16-43-15-14-42/h10-13,42H,2-9,14-39H2,1H3",FBALLGBRGQTMMZ-UHFFFAOYSA-N,C41H76O14,792.5235
+4,NPEO14,CCCCCCCCCc1ccccc1,CCCCCCCCCc1ccc(cc1)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C43H80O15/c1-2-3-4-5-6-7-8-9-42-10-12-43(13-11-42)58-41-40-57-39-38-56-37-36-55-35-34-54-33-32-53-31-30-52-29-28-51-27-26-50-25-24-49-23-22-48-21-20-47-19-18-46-17-16-45-15-14-44/h10-13,44H,2-9,14-41H2,1H3",FVJPEAADAOKTOQ-UHFFFAOYSA-N,C43H80O15,836.5497
+4,NPEO15,CCCCCCCCCc1ccccc1,CCCCCCCCCc1ccc(cc1)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C45H84O16/c1-2-3-4-5-6-7-8-9-44-10-12-45(13-11-44)61-43-42-60-41-40-59-39-38-58-37-36-57-35-34-56-33-32-55-31-30-54-29-28-53-27-26-52-25-24-51-23-22-50-21-20-49-19-18-48-17-16-47-15-14-46/h10-13,46H,2-9,14-43H2,1H3",KWHLVBVRNXHSAN-UHFFFAOYSA-N,C45H84O16,880.5759
+4,NPEO16,CCCCCCCCCc1ccccc1,CCCCCCCCCc1ccc(cc1)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C47H88O17/c1-2-3-4-5-6-7-8-9-46-10-12-47(13-11-46)64-45-44-63-43-42-62-41-40-61-39-38-60-37-36-59-35-34-58-33-32-57-31-30-56-29-28-55-27-26-54-25-24-53-23-22-52-21-20-51-19-18-50-17-16-49-15-14-48/h10-13,48H,2-9,14-45H2,1H3",WCERPFOWRLXYQI-UHFFFAOYSA-N,C47H88O17,924.6022
+4,NPEO17,CCCCCCCCCc1ccccc1,CCCCCCCCCc1ccc(cc1)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C49H92O18/c1-2-3-4-5-6-7-8-9-48-10-12-49(13-11-48)67-47-46-66-45-44-65-43-42-64-41-40-63-39-38-62-37-36-61-35-34-60-33-32-59-31-30-58-29-28-57-27-26-56-25-24-55-23-22-54-21-20-53-19-18-52-17-16-51-15-14-50/h10-13,50H,2-9,14-47H2,1H3",XYFPAHRNVLCKAN-UHFFFAOYSA-N,C49H92O18,968.6284
+4,NPEO18,CCCCCCCCCc1ccccc1,CCCCCCCCCc1ccc(cc1)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C51H96O19/c1-2-3-4-5-6-7-8-9-50-10-12-51(13-11-50)70-49-48-69-47-46-68-45-44-67-43-42-66-41-40-65-39-38-64-37-36-63-35-34-62-33-32-61-31-30-60-29-28-59-27-26-58-25-24-57-23-22-56-21-20-55-19-18-54-17-16-53-15-14-52/h10-13,52H,2-9,14-49H2,1H3",ZZZCKEGAUVPGMK-UHFFFAOYSA-N,C51H96O19,1012.6546
+4,NPEO19,CCCCCCCCCc1ccccc1,CCCCCCCCCc1ccc(cc1)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C53H100O20/c1-2-3-4-5-6-7-8-9-52-10-12-53(13-11-52)73-51-50-72-49-48-71-47-46-70-45-44-69-43-42-68-41-40-67-39-38-66-37-36-65-35-34-64-33-32-63-31-30-62-29-28-61-27-26-60-25-24-59-23-22-58-21-20-57-19-18-56-17-16-55-15-14-54/h10-13,54H,2-9,14-51H2,1H3",IFTNLPDUPBHEEO-UHFFFAOYSA-N,C53H100O20,1056.6808
+4,NPEO20,CCCCCCCCCc1ccccc1,CCCCCCCCCc1ccc(cc1)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C55H104O21/c1-2-3-4-5-6-7-8-9-54-10-12-55(13-11-54)76-53-52-75-51-50-74-49-48-73-47-46-72-45-44-71-43-42-70-41-40-69-39-38-68-37-36-67-35-34-66-33-32-65-31-30-64-29-28-63-27-26-62-25-24-61-23-22-60-21-20-59-19-18-58-17-16-57-15-14-56/h10-13,56H,2-9,14-53H2,1H3",JHJHUANFXVWPNF-UHFFFAOYSA-N,C55H104O21,1100.707
+-1,NPEO2-SO4,,O=S(=O)(O)OCCOCCOc1ccc(cc1)CCCCCCCCC,"InChI=1S/C19H32O6S/c1-2-3-4-5-6-7-8-9-18-10-12-19(13-11-18)24-16-14-23-15-17-25-26(20,21)22/h10-13H,2-9,14-17H2,1H3,(H,20,21,22)",LTPRIPYCXJPJLM-UHFFFAOYSA-N,C19H32O6S,388.192
+4,NPEO3-SO4,CCCCCCCCCc1ccccc1,O=S(=O)(O)OCCOCCOCCOc1ccc(cc1)CCCCCCCCC,"InChI=1S/C21H36O7S/c1-2-3-4-5-6-7-8-9-20-10-12-21(13-11-20)27-18-16-25-14-15-26-17-19-28-29(22,23)24/h10-13H,2-9,14-19H2,1H3,(H,22,23,24)",GYJFYRKHKPMLJY-UHFFFAOYSA-N,C21H36O7S,432.2182
+4,NPEO4-SO4,CCCCCCCCCc1ccccc1,O=S(=O)(O)OCCOCCOCCOCCOc1ccc(cc1)CCCCCCCCC,"InChI=1S/C23H40O8S/c1-2-3-4-5-6-7-8-9-22-10-12-23(13-11-22)30-20-18-28-16-14-27-15-17-29-19-21-31-32(24,25)26/h10-13H,2-9,14-21H2,1H3,(H,24,25,26)",JYUQOKPBOVCAMU-UHFFFAOYSA-N,C23H40O8S,476.2444
+4,NPEO5-SO4,CCCCCCCCCc1ccccc1,O=S(=O)(O)OCCOCCOCCOCCOCCOc1ccc(cc1)CCCCCCCCC,"InChI=1S/C25H44O9S/c1-2-3-4-5-6-7-8-9-24-10-12-25(13-11-24)33-22-20-31-18-16-29-14-15-30-17-19-32-21-23-34-35(26,27)28/h10-13H,2-9,14-23H2,1H3,(H,26,27,28)",FEODFOVQSHKNKS-UHFFFAOYSA-N,C25H44O9S,520.2706
+4,NPEO6-SO4,CCCCCCCCCc1ccccc1,O=S(=O)(O)OCCOCCOCCOCCOCCOCCOc1ccc(cc1)CCCCCCCCC,"InChI=1S/C27H48O10S/c1-2-3-4-5-6-7-8-9-26-10-12-27(13-11-26)36-24-22-34-20-18-32-16-14-31-15-17-33-19-21-35-23-25-37-38(28,29)30/h10-13H,2-9,14-25H2,1H3,(H,28,29,30)",DCVXQTZKGDLQBC-UHFFFAOYSA-N,C27H48O10S,564.2968
+4,NPEO7-SO4,CCCCCCCCCc1ccccc1,O=S(=O)(O)OCCOCCOCCOCCOCCOCCOCCOc1ccc(cc1)CCCCCCCCC,"InChI=1S/C29H52O11S/c1-2-3-4-5-6-7-8-9-28-10-12-29(13-11-28)39-26-24-37-22-20-35-18-16-33-14-15-34-17-19-36-21-23-38-25-27-40-41(30,31)32/h10-13H,2-9,14-27H2,1H3,(H,30,31,32)",LGPDXHJBISUFCI-UHFFFAOYSA-N,C29H52O11S,608.323
+4,NPEO8-SO4,CCCCCCCCCc1ccccc1,O=S(=O)(O)OCCOCCOCCOCCOCCOCCOCCOCCOc1ccc(cc1)CCCCCCCCC,"InChI=1S/C31H56O12S/c1-2-3-4-5-6-7-8-9-30-10-12-31(13-11-30)42-28-26-40-24-22-38-20-18-36-16-14-35-15-17-37-19-21-39-23-25-41-27-29-43-44(32,33)34/h10-13H,2-9,14-29H2,1H3,(H,32,33,34)",AJMIMOSFEVIRIA-UHFFFAOYSA-N,C31H56O12S,652.3492
+4,NPEO9-SO4,CCCCCCCCCc1ccccc1,O=S(=O)(O)OCCOCCOCCOCCOCCOCCOCCOCCOCCOc1ccc(cc1)CCCCCCCCC,"InChI=1S/C33H60O13S/c1-2-3-4-5-6-7-8-9-32-10-12-33(13-11-32)45-30-28-43-26-24-41-22-20-39-18-16-37-14-15-38-17-19-40-21-23-42-25-27-44-29-31-46-47(34,35)36/h10-13H,2-9,14-31H2,1H3,(H,34,35,36)",SPRDWZPIHOHLNP-UHFFFAOYSA-N,C33H60O13S,696.3755
+4,NPEO10-SO4,CCCCCCCCCc1ccccc1,O=S(=O)(O)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOc1ccc(cc1)CCCCCCCCC,"InChI=1S/C35H64O14S/c1-2-3-4-5-6-7-8-9-34-10-12-35(13-11-34)48-32-30-46-28-26-44-24-22-42-20-18-40-16-14-39-15-17-41-19-21-43-23-25-45-27-29-47-31-33-49-50(36,37)38/h10-13H,2-9,14-33H2,1H3,(H,36,37,38)",IWVQJTNBNNBXIG-UHFFFAOYSA-N,C35H64O14S,740.4017
+4,NPEO11-SO4,CCCCCCCCCc1ccccc1,O=S(=O)(O)OCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOc1ccc(cc1)CCCCCCCCC,"InChI=1S/C37H68O15S/c1-2-3-4-5-6-7-8-9-36-10-12-37(13-11-36)51-34-32-49-30-28-47-26-24-45-22-20-43-18-16-41-14-15-42-17-19-44-21-23-46-25-27-48-29-31-50-33-35-52-53(38,39)40/h10-13H,2-9,14-35H2,1H3,(H,38,39,40)",OSRUJPQKBHRLGK-UHFFFAOYSA-N,C37H68O15S,784.4279
+-1,NP1EC,,CCCCCCCCCc1ccc(cc1)OCCOCC(=O)O,"InChI=1S/C19H30O4/c1-2-3-4-5-6-7-8-9-17-10-12-18(13-11-17)23-15-14-22-16-19(20)21/h10-13H,2-9,14-16H2,1H3,(H,20,21)",RAQHOBRSMPMJIP-UHFFFAOYSA-N,C19H30O4,322.2144
+4,NP2EC,CCCCCCCCCc1ccccc1,CCCCCCCCCc1ccc(cc1)OCCOCCOCC(=O)O,"InChI=1S/C21H34O5/c1-2-3-4-5-6-7-8-9-19-10-12-20(13-11-19)26-17-16-24-14-15-25-18-21(22)23/h10-13H,2-9,14-18H2,1H3,(H,22,23)",JYQIQTZWGQBTGK-UHFFFAOYSA-N,C21H34O5,366.2406
+-1,PEG-3EO,,CCOCCOCCO,"InChI=1S/C6H14O3/c1-2-8-5-6-9-4-3-7/h7H,2-6H2,1H3",XXJWXESWEXIICW-UHFFFAOYSA-N,C6H14O3,134.0943
+-1,PEG-4EO,,CCOCCOCCOCCO,"InChI=1S/C8H18O4/c1-2-10-5-6-12-8-7-11-4-3-9/h9H,2-8H2,1H3",WFSMVVDJSNMRAR-UHFFFAOYSA-N,C8H18O4,178.1205
+-1,PEG-5EO,,CCOCCOCCOCCOCCO,"InChI=1S/C10H22O5/c1-2-12-5-6-14-9-10-15-8-7-13-4-3-11/h11H,2-10H2,1H3",GTAKOUPXIUWZIA-UHFFFAOYSA-N,C10H22O5,222.1467
+-1,PEG-6EO,,CCOCCOCCOCCOCCOCCO,"InChI=1S/C12H26O6/c1-2-14-5-6-16-9-10-18-12-11-17-8-7-15-4-3-13/h13H,2-12H2,1H3",NJRFAMBTWHGSDE-UHFFFAOYSA-N,C12H26O6,266.1729
+-1,PEG-7EO,,CCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C14H30O7/c1-2-16-5-6-18-9-10-20-13-14-21-12-11-19-8-7-17-4-3-15/h15H,2-14H2,1H3",UKXKPKBTMYNOFS-UHFFFAOYSA-N,C14H30O7,310.1992
+-1,PEG-8EO,,CCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C16H34O8/c1-2-18-5-6-20-9-10-22-13-14-24-16-15-23-12-11-21-8-7-19-4-3-17/h17H,2-16H2,1H3",PJWQOENWHPEPKI-UHFFFAOYSA-N,C16H34O8,354.2254
+-1,PEG-9EO,,CCOCCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C18H38O9/c1-2-20-5-6-22-9-10-24-13-14-26-17-18-27-16-15-25-12-11-23-8-7-21-4-3-19/h19H,2-18H2,1H3",CUDPPTPIUWYGFI-UHFFFAOYSA-N,C18H38O9,398.2516
+-1,PEG-10EO,,CCOCCOCCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C20H42O10/c1-2-22-5-6-24-9-10-26-13-14-28-17-18-30-20-19-29-16-15-27-12-11-25-8-7-23-4-3-21/h21H,2-20H2,1H3",YENAMIVHUIKARM-UHFFFAOYSA-N,C20H42O10,442.2778
+-1,PEG-11EO,,CCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C22H46O11/c1-2-24-5-6-26-9-10-28-13-14-30-17-18-32-21-22-33-20-19-31-16-15-29-12-11-27-8-7-25-4-3-23/h23H,2-22H2,1H3",XUIHSBSMRCNZOZ-UHFFFAOYSA-N,C22H46O11,486.304
+-1,PEG-12EO,,CCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C24H50O12/c1-2-26-5-6-28-9-10-30-13-14-32-17-18-34-21-22-36-24-23-35-20-19-33-16-15-31-12-11-29-8-7-27-4-3-25/h25H,2-24H2,1H3",SSQHEMPOJNIWDV-UHFFFAOYSA-N,C24H50O12,530.3302
+-1,PEG-13EO,,CCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C26H54O13/c1-2-28-5-6-30-9-10-32-13-14-34-17-18-36-21-22-38-25-26-39-24-23-37-20-19-35-16-15-33-12-11-31-8-7-29-4-3-27/h27H,2-26H2,1H3",HMLWUTSMMJVOLX-UHFFFAOYSA-N,C26H54O13,574.3564
+-1,PEG-14EO,,CCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCOCCO,"InChI=1S/C28H58O14/c1-2-30-5-6-32-9-10-34-13-14-36-17-18-38-21-22-40-25-26-42-28-27-41-24-23-39-20-19-37-16-15-35-12-11-33-8-7-31-4-3-29/h29H,2-28H2,1H3",IPVHOLGRGKTFCL-UHFFFAOYSA-N,C28H58O14,618.3827
diff --git a/output_CCO_3_eawagsurf/mols_pure_repeating_units.png b/output_CCO_3_eawagsurf/mols_pure_repeating_units.png
new file mode 100644
index 0000000..ea5f236
Binary files /dev/null and b/output_CCO_3_eawagsurf/mols_pure_repeating_units.png differ
diff --git a/output_CCO_3_eawagsurf/no_repeating_unit_matches.png b/output_CCO_3_eawagsurf/no_repeating_unit_matches.png
new file mode 100644
index 0000000..aa2239b
Binary files /dev/null and b/output_CCO_3_eawagsurf/no_repeating_unit_matches.png differ
diff --git a/output_CCO_3_eawagsurf/non_series_containing_repeating_unit.png b/output_CCO_3_eawagsurf/non_series_containing_repeating_unit.png
new file mode 100644
index 0000000..ded5803
Binary files /dev/null and b/output_CCO_3_eawagsurf/non_series_containing_repeating_unit.png differ
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..2b0239a
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,29 @@
+##########################
+# Setup.py Configuration #
+##########################
+[metadata]
+name = classify_homologues
+version = 0.0.1-dev
+description = A cheminformatics algorithm to classify homologous series.
+long_description = file: README.md
+long_description_content_type = text/markdown
+
+[options]
+install_requires =
+    rdkit-pypi
+    pandas
+    numpy
+    itertools
+    os
+    sys
+    matplotlib
+    #click
+    #mols2grid
+
+# Where is my code
+packages = find:
+package_dir =
+    = src
+
+[options.packages.find]
+where = src
\ No newline at end of file
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..0af9463
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+
+"""Setup module."""
+
+import setuptools
+
+if __name__ == "__main__":
+    setuptools.setup()
diff --git a/src/classify_homologues/__init__.py b/src/classify_homologues/__init__.py
new file mode 100644
index 0000000..224c7cf
--- /dev/null
+++ b/src/classify_homologues/__init__.py
@@ -0,0 +1,1 @@
+'''Classifying homologous series using RDKit.'''
\ No newline at end of file
diff --git a/src/classify_homologues/nextgen_classify_homols.py b/src/classify_homologues/nextgen_classify_homols.py
new file mode 100644
index 0000000..ba70a70
--- /dev/null
+++ b/src/classify_homologues/nextgen_classify_homols.py
@@ -0,0 +1,164 @@
+import os
+import sys
+import rdkit.Chem as Chem
+from utils import *
+from rdkit.Chem import AllChem
+import rdkit.Chem.rdchem as rdchem
+import rdkit.Chem.Draw as Draw
+import rdkit.Chem.Descriptors
+from rdkit.Chem import PandasTools
+from rdkit.Chem.Draw import IPythonConsole, MolsToGridImage
+#PandasTools.RenderImagesInAllDataFrames(images=True)
+import pandas as pd
+import numpy as np
+#from contextlib import redirect_stderr
+
+
+
+
+
+#Chem.WrapLogs()
+
+#from contextlib import redirect_stdout, redirect_stderr
+#import io, logging
+#import externallib
+#logging.basicConfig(filename='error.log', level=logging.DEBUG)
+
+#f = io.StringIO()
+#with redirect_stdout(f), redirect_stderr(f):
+#    result = externallib.check_result()
+#logging.info(f.getvalue())
+#print(result)
+#https://www.codeforests.com/2020/11/05/python-suppress-stdout-and-stderr/
+
+
+#read in smiles and labels, prepare repeating units
+smiles, mols = read_smiles_csv(sys.argv[1])
+labels = read_labels_csv(sys.argv[2])
+df = pd.DataFrame({ "SMILES":smiles, "Mols":mols, "Labels":labels})
+ru = setup_repeating_unit('[#6&H2]-')
+
+#perform RU detection
+mols_no_ru_matches, labels_mols_no_ru_matches, mols_with_ru, labels_mols_with_ru = detect_repeating_units(mols, labels, ru)
+
+#perform core detection
+patt1, cores1, patt2, cores2, empty_cores_idx = detect_homologue_cores(mols_with_ru, ru)
+
+#detect and output molecules made solely of RUs
+os.makedirs("output"+"/")
+mols_made_of_ru, labels_made_of_ru = detect_mols_made_of_ru(mols_with_ru, labels_mols_with_ru, empty_cores_idx)
+
+#generate canonical SMILES of largest molecule fragment in cores
+cores2_nonempty, cores2_nonempty_largest_molfrag_cano_smiles, cores2_nonempty_largest_molfrag = largest_core_molfrag_to_cano_smiles(cores2)
+
+
+##construct dataframe for inspection
+#finalise lists after filtering out mols_made_of_ru
+mols_with_ru = [j for i,j in enumerate(mols_with_ru) if (i not in empty_cores_idx)]
+labels_mols_with_ru = [j for i,j in enumerate(labels_mols_with_ru) if (i not in empty_cores_idx)]
+#filter out row with empty core after first chopping from all cols and output
+patt1 = [q for p,q in enumerate(patt1) if (p not in empty_cores_idx)]
+cores1 = [q for p,q in enumerate(cores1) if (p not in empty_cores_idx)]
+patt2 = [q for p,q in enumerate(patt2) if (p not in empty_cores_idx)]
+cores2 = [q for p,q in enumerate(cores2) if (p not in empty_cores_idx)]
+#first convert to smarts, then molfromsmarts, then sanitize
+#cores2_nonempty_smarts = [Chem.rdmolfiles.MolToSmarts(co) for co in cores2_nonempty]
+#cores2_nonempty_molfromsmarts = [Chem.MolFromSmarts(co) for co in cores2_nonempty_smarts] #generates QueryAtoms
+#[Chem.SanitizeMol(co) for co in cores2_nonempty_molfromsmarts]
+
+
+
+#build df to summarise SS match and chopping steps
+imp_df_nonempty= pd.DataFrame({#"Smiles":smiles,
+                   #"Mols":mols,
+                    "Mols": mols_with_ru,
+                    "Labels": labels_mols_with_ru,
+                    "patt1": [j for i,j in enumerate(patt1) if cores2[i].GetNumAtoms()>0],
+                    "Cores": [j for i,j in enumerate(cores1) if cores2[i].GetNumAtoms()>0],
+                    "Cores2": cores2_nonempty,
+                    "LargestMolFrag_sanitised": cores2_nonempty_largest_molfrag
+                    })#"cano_smiles_cores2": cores2_cano_smiles
+
+
+
+#populate new column in df with corresponding  cores2_nonempty_largestmolfrag_canosmiles for each row
+imp_df_nonempty["canoSMILES_LargestMolfrag_sanitised"] = cores2_nonempty_largest_molfrag_cano_smiles
+
+#assign SeriesNo to only those series with >1 member
+imp_df_nonempty['SeriesNo'] = imp_df_nonempty.groupby('canoSMILES_LargestMolfrag_sanitised').filter(lambda group: len(group) > 1).groupby('canoSMILES_LargestMolfrag_sanitised').ngroup()
+
+
+#merge imp_df_nonempty with df on mol
+result = pd.merge(df, imp_df_nonempty, how="left", on=["Mols","Labels"])
+
+#annotate no_alkyl mols AND series with 1 member to have negative SeriesNo
+result['SeriesNo'] = result['SeriesNo'].fillna(-1)
+result.SeriesNo = result.SeriesNo.astype(int)
+
+
+#calc further identifiers and descr; write into log file
+#with open('log.txt', 'w') as f:
+ #   with redirect_stderr(f):
+inchis = [Chem.inchi.MolToInchi(i) for i in result.Mols]
+inchikeys = [Chem.inchi.MolToInchiKey(i) for i in result.Mols]
+mf = [Chem.rdMolDescriptors.CalcMolFormula(i) for i in result.Mols]
+monoiso_mass = [round(Chem.Descriptors.ExactMolWt(i),4) for i in result.Mols]
+
+out = result[["SeriesNo","Labels","canoSMILES_LargestMolfrag_sanitised","SMILES", ]].copy()
+out['InChI'] = inchis
+out['InChIKey'] = inchikeys
+out['molecular_formula'] = mf
+out['monoisotopic_mass'] = monoiso_mass
+out.rename(columns={"SeriesNo":"series_no", "Labels":"series_name", "canoSMILES_LargestMolfrag_sanitised": "common_core"},inplace=True)
+out.to_csv('output/' + 'classified_series.csv',index=False)
+
+#plots per group - only series which have >1 member i.e. actual series
+result_pos_serno = result[result["SeriesNo"] > -1]
+#legends
+lgs = [i for i in result_pos_serno.groupby('canoSMILES_LargestMolfrag_sanitised').Labels.apply(list)]
+for i,j in enumerate(lgs):
+    lgs[i] = lgs[i] + ["core"]
+
+grpdmols = result_pos_serno.groupby('canoSMILES_LargestMolfrag_sanitised').SMILES.apply(list) #lists of SMILES
+for i,j in enumerate(grpdmols):
+    grpdmols[i] = grpdmols[i] + [grpdmols.keys()[i]]
+
+grpdmols = [[Chem.MolFromSmiles(s) for s in g] for g in grpdmols]
+
+list_grid_images = []
+for i,j in enumerate(grpdmols):
+    list_grid_images.append(DrawMolsZoomed(grpdmols[i], legends=lgs[i], molsPerRow=5))
+
+#plot nans i.e. those with no alkyls and therefore not classified
+#print(str(len(mols_no_alkyl_matches)) + ", " + str(len(labels_mols_no_alkyl_matches)))
+if len(mols_no_ru_matches) > 0:
+    nans = DrawMolsZoomed(mols=mols_no_ru_matches, legends=labels_mols_no_ru_matches, molsPerRow=5)
+    nans.save("output/" + "no_repeating_unit_matches.png")
+#print(len(mols_no_alkyl_matches))
+#nans = DrawMolsZoomed(mols=mols_no_alkyl_matches, legends=labels_mols_no_alkyl_matches, molsPerRow=5)
+#nans.save("output/" + "no_alkyl_matches.png")
+
+#save each plot per group
+[img.save("output/" + str(idx) + ".png") for idx,img in enumerate(list_grid_images)]
+
+
+#plot mols with alkyls but are 1-member series (i.e. not actually series)
+#SeriesNo = -1, SMILES is not empty
+
+onememseries = result.loc[(result['SeriesNo'] == -1) & (result['canoSMILES_LargestMolfrag_sanitised'].notnull())]
+if len(onememseries.Mols) >0:
+    mols_onememseries = [i for i in onememseries.Mols]
+    labs_onememseries = [i for i in onememseries.Labels]
+    pl_onememseries = DrawMolsZoomed(mols_onememseries,labs_onememseries,molsPerRow=5)
+    pl_onememseries.save("output/non_series_containing_repeating_unit.png")
+    print(str(len(onememseries.Mols))+ " molecule(s) have repeating unit matches of minimum x units but do not belong to any series.")
+
+
+num_series = result.SeriesNo.max()
+if num_series < 0:
+    num_series= 0
+
+#sys.stderr = old_stderr
+#assert sio.getvalue() != ""
+mols_classified = len(result.Mols)-len(onememseries.Mols)-len(mols_no_ru_matches)-len(mols_made_of_ru)
+print("Homologue classification complete! " + str(mols_classified) + " molecules have been classified into " +str(num_series) + " series." )
diff --git a/src/classify_homologues/output/0.png b/src/classify_homologues/output/0.png
new file mode 100644
index 0000000..0f9aa6a
Binary files /dev/null and b/src/classify_homologues/output/0.png differ
diff --git a/src/classify_homologues/output/1.png b/src/classify_homologues/output/1.png
new file mode 100644
index 0000000..9cd1a8a
Binary files /dev/null and b/src/classify_homologues/output/1.png differ
diff --git a/src/classify_homologues/output/2.png b/src/classify_homologues/output/2.png
new file mode 100644
index 0000000..b84d61d
Binary files /dev/null and b/src/classify_homologues/output/2.png differ
diff --git a/src/classify_homologues/output/classified_series.csv b/src/classify_homologues/output/classified_series.csv
new file mode 100644
index 0000000..4a837d9
--- /dev/null
+++ b/src/classify_homologues/output/classified_series.csv
@@ -0,0 +1,24 @@
+series_no,series_name,common_core,SMILES,InChI,InChIKey,molecular_formula,monoisotopic_mass
+1,C10-LAS,O=S(=O)(O)c1ccccc1,OS(=O)(=O)c1ccc(cc1)C(CCCCC)CCCC,"InChI=1S/C16H26O3S/c1-3-5-7-9-14(8-6-4-2)15-10-12-16(13-11-15)20(17,18)19/h10-14H,3-9H2,1-2H3,(H,17,18,19)",KIIODTIGNUGDLO-UHFFFAOYSA-N,C16H26O3S,298.1603
+1,C11-LAS,O=S(=O)(O)c1ccccc1,OS(=O)(=O)c1ccc(cc1)C(CCCCCC)CCCC,"InChI=1S/C17H28O3S/c1-3-5-7-8-10-15(9-6-4-2)16-11-13-17(14-12-16)21(18,19)20/h11-15H,3-10H2,1-2H3,(H,18,19,20)",FERBTPHUEYEGDN-UHFFFAOYSA-N,C17H28O3S,312.1759
+1,C12-LAS,O=S(=O)(O)c1ccccc1,OS(=O)(=O)c1ccc(cc1)C(CCCCCCC)CCCC,"InChI=1S/C18H30O3S/c1-3-5-7-8-9-11-16(10-6-4-2)17-12-14-18(15-13-17)22(19,20)21/h12-16H,3-11H2,1-2H3,(H,19,20,21)",FQWWBDRIEVYQEW-UHFFFAOYSA-N,C18H30O3S,326.1916
+1,C13-LAS,O=S(=O)(O)c1ccccc1,OS(=O)(=O)c1ccc(cc1)C(CCCCCCC)CCCCC,"InChI=1S/C19H32O3S/c1-3-5-7-8-10-12-17(11-9-6-4-2)18-13-15-19(16-14-18)23(20,21)22/h13-17H,3-12H2,1-2H3,(H,20,21,22)",DKWBEYOUIOCBBC-UHFFFAOYSA-N,C19H32O3S,340.2072
+1,C14-LAS,O=S(=O)(O)c1ccccc1,OS(=O)(=O)c1ccc(cc1)C(CCCCCCC)CCCCCC,"InChI=1S/C20H34O3S/c1-3-5-7-9-11-13-18(12-10-8-6-4-2)19-14-16-20(17-15-19)24(21,22)23/h14-18H,3-13H2,1-2H3,(H,21,22,23)",HFNZFDCGFGXPHN-UHFFFAOYSA-N,C20H34O3S,354.2229
+2,C10-SAS,O=[SH](=O)O,O=S(O)(=O)C(CCCCC)CCCC,"InChI=1S/C10H22O3S/c1-3-5-7-9-10(8-6-4-2)14(11,12)13/h10H,3-9H2,1-2H3,(H,11,12,13)",CLHWZDBKYXSFFK-UHFFFAOYSA-N,C10H22O3S,222.129
+2,C11-SAS,O=[SH](=O)O,O=S(O)(=O)C(CCCCCC)CCCC,"InChI=1S/C11H24O3S/c1-3-5-7-8-10-11(9-6-4-2)15(12,13)14/h11H,3-10H2,1-2H3,(H,12,13,14)",IWZVUKJVPRJMCV-UHFFFAOYSA-N,C11H24O3S,236.1446
+2,C12-SAS,O=[SH](=O)O,O=S(O)(=O)C(CCCCCCC)CCCC,"InChI=1S/C12H26O3S/c1-3-5-7-8-9-11-12(10-6-4-2)16(13,14)15/h12H,3-11H2,1-2H3,(H,13,14,15)",BSQQGKMAIODZDZ-UHFFFAOYSA-N,C12H26O3S,250.1603
+2,C13-SAS,O=[SH](=O)O,O=S(O)(=O)C(CCCCC)CCCCCCC,"InChI=1S/C13H28O3S/c1-3-5-7-8-10-12-13(17(14,15)16)11-9-6-4-2/h13H,3-12H2,1-2H3,(H,14,15,16)",KTVQXHPSFBSSTJ-UHFFFAOYSA-N,C13H28O3S,264.1759
+2,C14-SAS,O=[SH](=O)O,O=S(O)(=O)C(CCCCCCCCC)CCCC,"InChI=1S/C14H30O3S/c1-3-5-7-8-9-10-11-13-14(12-6-4-2)18(15,16)17/h14H,3-13H2,1-2H3,(H,15,16,17)",BTPXRGIPAXXPNB-UHFFFAOYSA-N,C14H30O3S,278.1916
+2,C15-SAS,O=[SH](=O)O,O=S(O)(=O)C(CCCCCCCCCC)CCCC,"InChI=1S/C15H32O3S/c1-3-5-7-8-9-10-11-12-14-15(13-6-4-2)19(16,17)18/h15H,3-14H2,1-2H3,(H,16,17,18)",PSHQOLNJGLLTDT-UHFFFAOYSA-N,C15H32O3S,292.2072
+2,C16-SAS,O=[SH](=O)O,O=S(O)(=O)C(CCCCC)CCCCCCCCCC,"InChI=1S/C16H34O3S/c1-3-5-7-8-9-10-11-13-15-16(20(17,18)19)14-12-6-4-2/h16H,3-15H2,1-2H3,(H,17,18,19)",QVERVCKBMFECAK-UHFFFAOYSA-N,C16H34O3S,306.2229
+2,C17-SAS,O=[SH](=O)O,O=S(O)(=O)C(CCCCCC)CCCCCCCCCC,"InChI=1S/C17H36O3S/c1-3-5-7-9-10-11-12-14-16-17(21(18,19)20)15-13-8-6-4-2/h17H,3-16H2,1-2H3,(H,18,19,20)",YRQQPWVBSQEBPW-UHFFFAOYSA-N,C17H36O3S,320.2385
+2,C18-SAS,O=[SH](=O)O,O=S(O)(=O)C(CCCCCCC)CCCCCCCCCC,"InChI=1S/C18H38O3S/c1-3-5-7-9-10-11-13-15-17-18(22(19,20)21)16-14-12-8-6-4-2/h18H,3-17H2,1-2H3,(H,19,20,21)",YOXNJPLWSLWLQI-UHFFFAOYSA-N,C18H38O3S,334.2542
+2,C19-SAS,O=[SH](=O)O,O=S(O)(=O)C(CCCCCCCC)CCCCCCCCCC,"InChI=1S/C19H40O3S/c1-3-5-7-9-11-12-14-16-18-19(23(20,21)22)17-15-13-10-8-6-4-2/h19H,3-18H2,1-2H3,(H,20,21,22)",YXWDSEJGFLEXSH-UHFFFAOYSA-N,C19H40O3S,348.2698
+2,C20-SAS,O=[SH](=O)O,O=S(O)(=O)C(CCCCCCCCCC)CCCCCCCCC,"InChI=1S/C20H42O3S/c1-3-5-7-9-11-13-15-17-19-20(24(21,22)23)18-16-14-12-10-8-6-4-2/h20H,3-19H2,1-2H3,(H,21,22,23)",SDWPANLVMNASEQ-UHFFFAOYSA-N,C20H42O3S,362.2855
+-1,C21-SAS,CS(=O)(=O)O,O=S(O)(=O)C(CCCCCCCCCC)CCCCCCCCCC,"InChI=1S/C21H44O3S/c1-3-5-7-9-11-13-15-17-19-21(25(22,23)24)20-18-16-14-12-10-8-6-4-2/h21H,3-20H2,1-2H3,(H,22,23,24)",AQXMUZIEAPVCJB-UHFFFAOYSA-N,C21H44O3S,376.3011
+0,C7DEA,O=CN(CCO)CCO,O=C(CCCCCCC)N(CCO)CCO,"InChI=1S/C12H25NO3/c1-2-3-4-5-6-7-12(16)13(8-10-14)9-11-15/h14-15H,2-11H2,1H3",FZQAYFWUOCXLKJ-UHFFFAOYSA-N,C12H25NO3,231.1834
+0,C9DEA,O=CN(CCO)CCO,O=C(CCCCCCCCC)N(CCO)CCO,"InChI=1S/C14H29NO3/c1-2-3-4-5-6-7-8-9-14(18)15(10-12-16)11-13-17/h16-17H,2-13H2,1H3",BPXGKRUSMCVZAF-UHFFFAOYSA-N,C14H29NO3,259.2147
+0,C11DEA,O=CN(CCO)CCO,O=C(CCCCCCCCCCC)N(CCO)CCO,"InChI=1S/C16H33NO3/c1-2-3-4-5-6-7-8-9-10-11-16(20)17(12-14-18)13-15-19/h18-19H,2-15H2,1H3",AOMUHOFOVNGZAN-UHFFFAOYSA-N,C16H33NO3,287.246
+0,C13DEA,O=CN(CCO)CCO,O=C(CCCCCCCCCCCCC)N(CCO)CCO,"InChI=1S/C18H37NO3/c1-2-3-4-5-6-7-8-9-10-11-12-13-18(22)19(14-16-20)15-17-21/h20-21H,2-17H2,1H3",SKDZEPBJPGSFHS-UHFFFAOYSA-N,C18H37NO3,315.2773
+0,C15DEA,O=CN(CCO)CCO,O=C(CCCCCCCCCCCCCCC)N(CCO)CCO,"InChI=1S/C20H41NO3/c1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-20(24)21(16-18-22)17-19-23/h22-23H,2-19H2,1H3",VJESJEJNMGVQLZ-UHFFFAOYSA-N,C20H41NO3,343.3086
+0,C17DEA,O=CN(CCO)CCO,O=C(CCCCCCCCCCCCCCCCC)N(CCO)CCO,"InChI=1S/C22H45NO3/c1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-22(26)23(18-20-24)19-21-25/h24-25H,2-21H2,1H3",XGZOMURMPLSSKQ-UHFFFAOYSA-N,C22H45NO3,371.3399
diff --git a/src/classify_homologues/output/non_series_containing_repeating_unit.png b/src/classify_homologues/output/non_series_containing_repeating_unit.png
new file mode 100644
index 0000000..3790451
Binary files /dev/null and b/src/classify_homologues/output/non_series_containing_repeating_unit.png differ
diff --git a/src/classify_homologues/utils.py b/src/classify_homologues/utils.py
new file mode 100644
index 0000000..c2d5e92
--- /dev/null
+++ b/src/classify_homologues/utils.py
@@ -0,0 +1,151 @@
+from rdkit import Chem
+from rdkit.Chem import AllChem
+import numpy as np
+from rdkit.Chem.Draw import rdMolDraw2D
+from io import BytesIO
+from itertools import compress
+try:
+    import Image
+except ImportError:
+    from PIL import Image
+
+def read_smiles_csv(path_to_smiles_csv): #sys.argv[1]
+    '''Function to read in list of SMILES and create molecule objects.'''
+    with open(path_to_smiles_csv) as f:
+        smiles = [line.strip().replace('"','') for line in f]
+        mols = [AllChem.MolFromSmiles(smile) for smile in smiles]
+    return smiles, mols
+
+def read_labels_csv(path_to_labels_csv): #sys.argv[2]
+    '''Function to read in list of labels corresponding to SMILES.'''
+    with open(path_to_labels_csv) as f:
+        labels = [line.strip().replace('"','') for line in f]
+    return labels
+
+def setup_repeating_unit(smarts):
+    '''Function to generate list of RU chains as query molecules from SMARTS.'''
+    smiles_ru = []
+    #[smiles_ru.append(sys.argv[3]*i) for i in range(1,31)] ##most generic form, taking RU SMILES input
+    [smiles_ru.append(smarts*i) for i in range(1,31)]
+    smiles_ru = smiles_ru[2:] #eliminate meth- and eth- as they are too short
+    smiles_ru = [x[:-1] for x in smiles_ru] #remove last hyphen in each string
+    ru = [Chem.MolFromSmarts(smi) for smi in smiles_ru]
+    return ru
+
+def detect_repeating_units(mols, labels, ru):
+    '''Function to detect whether molecules contain repeating units.'''
+    # set up RU-match matrix for detection of RU in mols
+    mat1 = SubstructMatchMatrix_ru_mols(mols, ru, accountForRings=True)
+    mat_array_sums = []
+    length_ru_chains_to_chop = []
+    for x, y in enumerate(mat1):
+        mat_array_sums.append(int(np.sum(mat1[x])))
+        length_ru_chains_to_chop.append(mat_array_sums[x] + 2)  # n = sum + 2, where n is the length of C chain to chop
+    n_mols_no_ru = mat_array_sums.count(0)
+    if n_mols_no_ru>0:
+        print(str(n_mols_no_ru) + " mols have no repeating unit chains of minimum 3 repeating units in length.")
+    #remove mols with no RU matches
+    fil_ru = []
+    fil_ru = [bool(x) for x in mat_array_sums] #those which are False have array_sum = 0 i.e. no alkyls
+    mols_no_ru_matches = list(compress(mols, [not i for i in fil_ru]))
+    labels_mols_no_ru_matches = list(compress(labels, [not i for i in fil_ru]))
+    mols_with_ru = list(compress(mols, fil_ru))
+    labels_mols_with_ru = list(compress(labels, fil_ru))
+    return mols_no_ru_matches, labels_mols_no_ru_matches, mols_with_ru, labels_mols_with_ru
+
+def detect_homologue_cores(mols_with_ru, ru):
+    '''Function that performs RU matching-and-removal twice to isolate/detect cores in molecule object. Idxs of empty cores generated.'''
+    mat2 = SubstructMatchMatrix_ru_mols(mols_with_ru, ru, accountForRings=True) #set up RU-match matrix for 1st RU removal from mols with RU
+    patt1, cores1 = delete_longest_RU_match(mols_with_ru, mat2, ru) #first removal
+    empty_cores_idx = [i for i, j in enumerate(cores1) if j.GetNumAtoms() == 0] #isolate empty cores' idxs after first chopping, occur when mol is 100% made of RU
+    mat3 = SubstructMatchMatrix_ru_mols(cores1, ru, accountForRings=True) #set up RU-match matrix for 2nd RU removal from cores1
+    patt2, cores2 = delete_longest_RU_match(cores1, mat3, ru) #second removal
+    return patt1, cores1, patt2, cores2, empty_cores_idx
+
+def detect_mols_made_of_ru(mols_with_ru, labels_mols_with_ru, empty_cores_idx):
+    '''Function to detect and output molecules made solely of RUs such as PEGs.'''
+    mols_made_of_ru = [j for i,j in enumerate(mols_with_ru) if (i in empty_cores_idx)] #isolate Mol and Label with empty core after first chopping i.e. entire mol is made of ru
+    labels_made_of_ru = [j for i, j in enumerate(labels_mols_with_ru) if (i in empty_cores_idx)]
+    if len(mols_made_of_ru) > 0:
+        pure_repeating_units = DrawMolsZoomed(mols_made_of_ru, labels_made_of_ru)
+        pure_repeating_units.save("output/mols_pure_repeating_units.png")
+        print(str(len(mols_made_of_ru)) + " molecule(s) are made purely of repeating units of minimum length x.")
+    return mols_made_of_ru, labels_made_of_ru
+
+
+def DrawMolsZoomed(mols, legends, molsPerRow=3, subImgSize=(300, 300)):#, leg):
+    """Function to draw rows of zoomed molecules. Credit Rocco Moretti."""
+    nRows = len(mols) // molsPerRow
+    if len(mols) % molsPerRow: nRows += 1
+    fullSize = (molsPerRow * subImgSize[0], nRows * subImgSize[1])
+    full_image = Image.new('RGBA', fullSize )
+    for ii, mol in enumerate(mols):
+        if mol.GetNumConformers() == 0:
+            AllChem.Compute2DCoords(mol)
+        le = legends[ii]
+        column = ii % molsPerRow
+        row = ii // molsPerRow
+        offset = ( column*subImgSize[0], row * subImgSize[1] )
+        d2d = rdMolDraw2D.MolDraw2DCairo(subImgSize[0], subImgSize[1])
+        d2d.DrawMolecule(mol,legend=le)
+        d2d.FinishDrawing()
+        sub = Image.open(BytesIO(d2d.GetDrawingText()))
+        full_image.paste(sub,box=offset)
+    return full_image
+
+#from https://sourceforge.net/p/rdkit/mailman/rdkit-discuss/thread/CAHGTkV8sdfb4Q7FLn9C5MTwrqiJjHtnXK%2Bmz2SY3_4j2eAtevQ%40mail.gmail.com/#msg36477772
+
+
+
+def hasSubstructMatchAccountForRings(mol, q):
+    """Function to exclude substructure matches if they are part of rings. Credit Paolo Tosco."""
+    matches = mol.GetSubstructMatches(q)
+    hasMatch = False
+    for match in matches:
+        hasMatch = True
+        for i, j in enumerate(match):
+            if (q.GetAtomWithIdx(i).IsInRing() ^ mol.GetAtomWithIdx(j).IsInRing()):
+                hasMatch = False
+                break
+        if (hasMatch):
+            break
+    return hasMatch
+
+#from https://gist.github.com/ptosco/26af473fc1f3129878ca86cb070afe3a
+
+
+def SubstructMatchMatrix_ru_mols(mols, ru, accountForRings=True):
+    '''Function to generate matrix of 1s and 0s for RU substructure matching in molecules.'''
+    mat = np.zeros((len(mols), len(ru)))
+    for a,b in enumerate(mols):
+        for i,j in enumerate(ru):
+            if accountForRings:
+                mat[a,i] = hasSubstructMatchAccountForRings(b,j)
+            else:
+                mat[a,i] = mols[a].HasSubstructMatch(j)
+    return mat
+
+
+def delete_longest_RU_match(mols, mat, ru):
+    '''Function to delete the longest RU substructure match from each molecule. Returns remaining cores and the RU deleted.'''
+    cores = list()
+    patt = list()
+    for x,y in enumerate(mols):
+        patt.append(ru[int(np.sum(mat[x])-1)])
+        cores.append(AllChem.DeleteSubstructs(y, patt[x]))
+    return patt, cores
+
+def largest_core_molfrag_to_cano_smiles(cores2):
+    '''Function to isolate the largest molecule fragment by NumAtoms remaining in the core object and convert to canonical SMILES.'''
+    cores2_nonempty = [j for i, j in enumerate(cores2) if j.GetNumAtoms() > 0] # isolate non-empty cores after chopping
+    cores2_nonempty_molfrags = [Chem.GetMolFrags(co, asMols=True) for co in cores2_nonempty]  # cores2_nonempty_molfromsmarts
+    cores2_nonempty_largest_molfrag = []
+    for i, j in enumerate(cores2_nonempty_molfrags):  # get the largest molfrag of all molfrags
+        cores2_nonempty_largest_molfrag.append(max(cores2_nonempty_molfrags[i],
+                                                   default=cores2_nonempty_molfrags[i],
+                                                   key=lambda m: m.GetNumAtoms()
+                                                   )
+                                               )
+    cores2_nonempty_largest_molfrag_smiles = [Chem.MolToSmiles(co) for co in cores2_nonempty_largest_molfrag]
+    cores2_nonempty_largest_molfrag_cano_smiles = [Chem.CanonSmiles(smi) for smi in cores2_nonempty_largest_molfrag_smiles]
+    return cores2_nonempty, cores2_nonempty_largest_molfrag_cano_smiles, cores2_nonempty_largest_molfrag


Test patch:
diff --git a/input/test4_labels_20 b/input/test2_labels_20
similarity index 100%
rename from input/test4_labels_20
rename to input/test2_labels_20
diff --git a/input/test4_smiles_20 b/input/test2_smiles_20
similarity index 100%
rename from input/test4_smiles_20
rename to input/test2_smiles_20
diff --git a/input/test2_labels_43.csv b/input/test3_labels_43.csv
similarity index 100%
rename from input/test2_labels_43.csv
rename to input/test3_labels_43.csv
diff --git a/input/test2_smiles_43.csv b/input/test3_smiles_43.csv
similarity index 100%
rename from input/test2_smiles_43.csv
rename to input/test3_smiles_43.csv
diff --git a/input/test3_labels_75.csv b/input/test4_labels_75.csv
similarity index 100%
rename from input/test3_labels_75.csv
rename to input/test4_labels_75.csv
diff --git a/input/test3_smiles_75.csv b/input/test4_smiles_75.csv
similarity index 100%
rename from input/test3_smiles_75.csv
rename to input/test4_smiles_75.csv