Whilst the rule of 5 (Ro5) has provided a useful way to describe small molecule drug space it is also clear that there are a significant number of molecular classes that exist beyond the rule of 5 boundaries (bRo5). In a review of the AbbVie compound collection DOI they were able to identify key findings that might explain the success (or failure) of bRo5 projects. From an analysis of a variety of calculated physicochemical properties they proposed a simple multiparametric scoring function (AB-MPS) was devised that correlated preclinical PK results with cLogD, number of rotatable bonds, and number of aromatic rings.
AB-MPS = Abs(cLogD-3) + NAR + NRB
Where cLogD was the calculated LogD (ChemAxon), NAR is number of aromatic rings, NRB is number of rotatable bonds (pipeline pilot calculations), with AB-MPS values of ≤14 predicting a higher probability of success. Compounds with AB-MPS <14 on average had better bioavailability and PAMPA cell penetration.
One of the issues with implementing this sort of scoring function is that different tools (or even different versions) can give slightly different results. Fortunately in the supplementary information they provide the calculated results for around 135 known oral and parental drugs that would be considered to be beyond the rule of 5. These can be extracted from the pdf using Tabula and imported into Vortex, the structures were then generated from the names using a script. I found I had to do a little tidying to get rid of counterions, solvates etc.
We can use evaluate from ChemAxon to calculate the parameters needed,
1 2 |
/Applications/ChemAxon/MarvinBeans/bin/evaluate', sdfFile, '-g', '-e', "logd('7.4'); rotatablebondcount(); aromaticRingCount()"] |
then populate the columns in the table. Finally get the values from the table and calculate the AB_MPS and populate the column.
1 2 |
TheScore = abs(mollogD - 3) + molRBC + molNar |
The Vortex Script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# Created by http://www.macinchem.org # Requires ChemAxon commandline import sys #sys.path.append(vortex.getVortexFolder() + '/modules/jythonlib') import subprocess #Results go in here colabmps= vtable.findColumnWithName('ABmps', 1, vortex.DOUBLE) # Get the path to the currently open sdf file sdfFile = vortex.getFileForPropertyCalculation(vtable) # http://www.chemaxon.com/ # Use Evaluate on the file # command format '/Applications/ChemAxon/MarvinBeans/bin/evaluate' '/Users/username/Desktop/Today/Summary.sdf' -g -e "molString('smiles'); logp(); logd('7.4'); apka('1'); bpka('1'); atomCount(); mass(); acceptorcount(); donorcount(); psa(); rotatablebondcount(); atomCount()-atomCount('1');aromaticAtomCount()/(atomCount()-atomCount('1'))" p = subprocess.Popen(['/Applications/ChemAxon/MarvinBeans/bin/evaluate', sdfFile, '-g', '-e', "logd('7.4'); rotatablebondcount(); aromaticRingCount()"], stdout=subprocess.PIPE) output = p.communicate()[0] # Create new columns in table if needed cols = "logD;RBC;Nar" colName = cols.split(';') for c in colName: column = vtable.findColumnWithName(c, 1, 1) vtable.fireTableStructureChanged() lines = output.split('\n') keys = [] for i in lines: words = i.split(';') if len(words) == 2: keys.append(words[0]) # Parse the output rows = lines[0:len(lines)] for r in range(0, vtable.getRealRowCount()): vals = rows[r].split(';') for j in range(0, len(vals)): column = vtable.findColumnWithName(colName[j], 0) column.setValueFromString(r, vals[j]) # Calculate ABMPS # check if there is no logD collogD = vtable.findColumnWithName('logD', 0) colRBC = vtable.findColumnWithName('RBC', 0) colNar = vtable.findColumnWithName('Nar', 0) rows = vtable.getRealRowCount() for r in range(0, int(rows)): logDExists = collogD.isDefined(r) if logDExists is True: mollogD = collogD.getValue(r) molRBC = colRBC.getValue(r) molNar = colNar.getValue(r) TheScore = abs(mollogD - 3) + molRBC + molNar column = vtable.findColumnWithName('ABmps', 1) column.setDouble(r, TheScore) vtable.fireTableStructureChanged() |
The results
A plot of AB_MPS (from support info) versus ABmps (this calculation), shown below, shows a few minor discrepancies.
On closer examination this appears to be differences in the rotatable bond count probably due to different tautomeric forms, shown below for tigecycline.
The data set also contained the route of administration and is shown in the plot below, I’ve plotted molecular weight on the x-axis and AB-MPS on the y-axis. Oral drugs are in blue and parenteral in green. As you can see molecules with an AB-MPS score of < 18 have a reasonable chance of oral availability despite having molecular > 500.
The script can be downloaded from here.
Last updated 12 May 2018