SDF file format: how SDF and MOL files work

Read a structure-data file line by line, and convert it without losing chemistry

20 min

Acetic acid drawn at the coordinates of its SDF atom block, eight atoms and seven bonds, magnified from the top record in a stack of records.

Download acetic acid from PubChem as an SDF and you get a text file of 122 lines. The molecule takes the first 20: three header lines, a counts line, one line for each of its eight atoms, one for each of its seven bonds, and an M END. The next 101 lines hold 33 named data fields, from the PubChem CID to a molecular weight of 60.05, and the last line is four dollar signs.

That split is the whole design of the structure-data file. A connection table records the atoms and bonds, and free-form data fields carry whatever a database or program wants to attach. SDF is what PubChem and ChEMBL hand out and what docking programs such as DiffDock and GNINA write. It is also the input AutoDock Vina's documentation prefers for ligand preparation, the step the SDF to PDBQT converter runs before AutoDock Vina.[1]

SDF and MOL files are one format

A molfile (.mol) describes one molecule, which may contain disconnected pieces such as a salt and its counterion. An SDfile (.sdf, sometimes .sd) is a run of molfiles, each optionally followed by data items and closed by a $$$$ line, so one file can hold a single compound or a whole library.[2]

Both belong to the CTfile family created at Molecular Design Limited (MDL), which described the formats in the literature in 1992.[3] They are now maintained by BIOVIA, part of Dassault Systèmes, and its CTfile specification is the reference for the layout below.[2] Every format in the family is built on the same connection table, or CTAB: a list of atoms with coordinates and a list of bonds between them.

SDF is a small-molecule format. Proteins and nucleic acids travel as PDB or mmCIF files, and a SMILES string records the same atoms and bonds as an SDF on one line, without coordinates.

Anatomy of an SDF record

Here is PubChem's 2D record for acetic acid (CID 176), with its data fields cut to four of the 33:

Text
176
  -OEChem-10302611462D

  8  7  0     0  0  0  0  0  0999 V2000
    3.7321    0.7500    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
    2.8660   -0.7500    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
    2.0000    0.7500    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
    2.8660    0.2500    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
    2.3100    1.2869    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
    1.4631    1.0600    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
    1.6900    0.2131    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
    4.2690    0.4400    0.0000 H   0  0  0  0  0  0  0  0  0  0  0  0
  1  4  1  0  0  0  0
  1  8  1  0  0  0  0
  2  4  2  0  0  0  0
  3  4  1  0  0  0  0
  3  5  1  0  0  0  0
  3  6  1  0  0  0  0
  3  7  1  0  0  0  0
M  END
> <PUBCHEM_COMPOUND_CID>
176

> <PUBCHEM_IUPAC_NAME>
acetic acid

> <PUBCHEM_MOLECULAR_FORMULA>
C2H4O2

> <PUBCHEM_SMILES>
CC(=O)O

$$$$
LinesBlockIn this record
1Header: molecule name176, the PubChem CID
2Header: program lineWritten by OEChem, with a timestamp and the dimensional code 2D
3Header: commentBlank
4Counts line8 atoms, 7 bonds, chiral flag 0, version V2000
5 to 12Atom blockCoordinates, element and per-atom fields for 2 oxygens, 2 carbons and 4 hydrogens
13 to 19Bond blockFirst atom, second atom, bond type and stereo for 7 bonds
20End of the moleculeM END
21 to 32Data itemsFour fields, each a header line, a value and a blank line
33Record separatorFour dollar signs
Table 1. The parts of the acetic acid record. Line numbers count from the top of the record above. Source: BIOVIA CTfile formats (2020).[2]

Header block

The first three lines are free text, but none of them can be skipped: a missing name or comment still takes a blank line.[2] Line 1 is the molecule name, which PubChem fills with the CID and ChEMBL with the ChEMBL ID. It must not contain the reserved tags of other CTfile types, including the four dollar signs that end an SDF record.

Line 2 packs the user's initials, the program name, a date and time, and a two-character dimensional code into fixed columns. In -OEChem-10302611462D, the initials are blank, the program is OEChem, 1030261146 is 30 October 2026 at 11:46, the moment PubChem generated the file, and 2D says the coordinates are flat. Line 3 is a comment, blank here.

Counts line

Line 4 is the counts line. Its V2000 fields are three characters wide: number of atoms, number of bonds, number of atom lists, an obsolete field, the chiral flag, five more obsolete fields, a properties count that writers now always set to 999, and the version stamp V2000.[2]

Because the widths are fixed, three-digit numbers run together. The ChEMBL compound CHEMBL440060 has 206 atoms and 208 bonds, and its counts line starts 206208. A parser that splits the line on whitespace instead of counting columns reads that as one number.

Atom and bond blocks

Each atom line starts with x, y and z coordinates in ten-character fields with four decimals, then the element symbol, then a row of small integer fields. Most of those fields belong to substructure queries and reactions and stay zero in ordinary files. The ones that matter are the mass difference for isotopes and the charge code; the stereo parity field is ignored when a file is read, because stereochemistry is worked out from the coordinates and bond wedges.[2]

Each bond line names two atoms by their position in the atom block and gives a bond type: 1 single, 2 double, 3 triple. In acetic acid, 2 4 2 is the double bond between the carbonyl oxygen (atom 2) and the carboxyl carbon (atom 4). The next field holds wedge and hash stereo for single bonds, with the narrow end of the wedge on the first atom.[2]

The specification also defines bond type 4 for aromatic bonds, but lists it, along with types 5 to 8, as a feature for substructure queries.[2] Files meant for exchange store aromatic rings in Kekulé form, with alternating single and double bonds. That is what RDKit writes for benzene, and what PubChem and ChEMBL records contain.

Properties block and M END

Between the bond block and M END sit property lines that begin with M and two spaces. The common one is M CHG, which lists formal charges as atom and charge pairs. Acetate, the deprotonated form of acetic acid, written without hydrogens has four atoms, three bonds and one property line, M CHG 1 4 -1: one charge, on atom 4, of minus one.

M ISO and M RAD do the same for isotopes and radicals. When these lines are present they take precedence over the older charge and mass fields in the atom block, and a reader keeps going until it meets M END, the line that closes the molecule.[2] In a MOL file, M END is the last line.

Data fields and the record separator

Everything after M END belongs to the SDF layer. Each data item is a header line that starts with > and holds the field name in angle brackets, then one or more lines of value, then exactly one blank line. Field names start with a letter and may contain letters, digits and underscores, but no hyphens, periods or spaces. A line of four dollar signs ends the record, and the next molecule begins on the following line.[2]

Data fields have no fixed vocabulary. PubChem's 2D record carries 33, including the InChIKey, XLogP3 and topological polar surface area. ChEMBL's bulk download carries only chembl_id. A record with no data fields at all is still valid; the specification then allows no blank line between M END and the dollar signs.[2]

V2000 vs V3000

V3000 is the newer version of the connection table, and BIOVIA calls it the preferred one. Its own products still write V2000 by default to keep working with other software.[2] V3000 drops fixed columns for tagged, space-separated entries. Here is the same acetic acid molecule written by RDKit as V3000:

Text
176
     RDKit          2D

  0  0  0  0  0  0  0  0  0  0999 V3000
M  V30 BEGIN CTAB
M  V30 COUNTS 8 7 0 0 0
M  V30 BEGIN ATOM
M  V30 1 O 3.732100 0.750000 0.000000 0
M  V30 2 O 2.866000 -0.750000 0.000000 0
M  V30 3 C 2.000000 0.750000 0.000000 0
M  V30 4 C 2.866000 0.250000 0.000000 0
M  V30 5 H 2.310000 1.286900 0.000000 0
M  V30 6 H 1.463100 1.060000 0.000000 0
M  V30 7 H 1.690000 0.213100 0.000000 0
M  V30 8 H 4.269000 0.440000 0.000000 0
M  V30 END ATOM
M  V30 BEGIN BOND
M  V30 1 1 1 4
M  V30 2 1 1 8
M  V30 3 2 2 4
M  V30 4 1 3 4
M  V30 5 1 3 5
M  V30 6 1 3 6
M  V30 7 1 3 7
M  V30 END BOND
M  V30 END CTAB
M  END

The three header lines stay, so old readers can still recognize the file, and line 4 becomes a counts line of zeros whose only job is to carry the V3000 stamp. The real counts move to M V30 COUNTS, and the atoms and bonds sit in BEGIN and END blocks. Each line is at most 80 characters; a trailing hyphen continues an entry on the next line.[2]

The usual reason to meet V3000 is size. V2000 has three characters for the atom count and three for the bond count, so a molecule with more than 999 atoms or bonds cannot be written as V2000, and writers switch formats automatically. Large peptides and polymers with explicit hydrogens cross that limit.

V3000 is also required for enhanced stereochemistry, which can mark a group of stereocenters as racemic or of known relative configuration only.[2] A tool that reads only V2000 rejects these files, so if a converter refuses a large ligand, check line 4 for V3000.

2D and 3D coordinates, and explicit hydrogens

The same compound can arrive as a flat drawing or as a 3D shape, and the file looks the same either way. PubChem's 3D record for acetic acid has the identical counts line and bond block; only the coordinates and the 3D code on line 2 differ. In a 2D record every z coordinate is 0.0000, and the x and y values are laid out for drawing, not for chemistry. The specification reads a file marked 2D as 3D if any z coordinate is non-zero, so the coordinates themselves are the better check.[2]

That difference decides whether a file can be docked. AutoDock Vina changes a ligand's position, orientation and torsion angles, but keeps the bond angles and ring shapes it was given, so a flat input stays flat in every pose. The SDF to PDBQT converter will prepare a 2D record but warns that the coordinates remain 2D. SMILES to SDF builds a 3D conformer from a SMILES string, and Open Babel can generate 3D coordinates for an existing file.

PubChem's 3D records are computed, not measured. They come from the conformer generator OMEGA with the MMFF94s force field,[4] and PubChem makes them only for compounds with at most 50 heavy atoms and 15 rotatable bonds, built from common organic elements, as a single covalent unit rather than a salt or mixture, and with fewer than six undefined stereocenters.[5]

Vancomycin, with 101 heavy atoms, has no 3D record. A computed conformer is a sensible starting shape for docking, not the pose a molecule takes in a binding site.

Hydrogens are the other silent difference. PubChem writes every hydrogen as an atom, which is why its acetic acid has eight. ChEMBL's bulk SDF lists heavy atoms only, and a reader adds implicit hydrogens from each atom's usual valence and formal charge.[6] Both describe the same molecule.

A docking input, though, needs explicit hydrogens. Vina scores heavy atoms only, yet it reads the input hydrogens to decide which atoms are hydrogen-bond donors, so the protonation of the input still matters.[7]

Where SDF files come from

PubChem serves a 2D SDF for every compound and a 3D SDF for those that meet the PubChem3D criteria. The 3D record also carries MMFF94 partial charges, stored as a data field because the molfile has no column for them. PubChem download fetches both files by compound name, CID or InChIKey.

ChEMBL publishes its whole compound set as one compressed SDF per release, chembl_37.sdf.gz for release 37, with 2D coordinates written by RDKit.[6] For a single compound, ChEMBL download fetches the SDF by ChEMBL ID.

Docking programs write SDF too. DiffDock saves each ranked pose as its own SDF, and GNINA writes all of its ranked poses into one multi-record SDF. AutoDock Vina is the exception: it reads and writes PDBQT, and its documentation recommends converting the results back to SDF with Meeko.[1] The PDBQT to SDF converter does that export.

SDF vs MOL2 vs PDBQT for docking

Three small-molecule formats run through most docking work, and they disagree about what a ligand file should carry. SDF stores chemistry: elements, bond orders and formal charges. MOL2 adds force-field atom types and partial charges. PDBQT keeps only what AutoDock needs to score the ligand and move it.

PropertySDF and MOLMOL2PDBQT
OriginMDL, now BIOVIATripos SYBYLAutoDock, Scripps Research
LayoutFixed columns (V2000) or tagged lines (V3000)Free-format sections, one per record typePDB columns plus two extra fields
Bond ordersStored: single, double, tripleStored, with extra amide and aromatic typesNot stored; no bond records at all
Formal chargesStored in the atom block and M CHG linesNo field; implied by atom typesNot stored
Partial chargesOnly as a data fieldPer-atom columnPer-atom column
Atom typesElement symbolsSYBYL types such as C.ar and N.amAutoDock types such as A, OA and HD
HydrogensExplicit, or implicit from valenceExplicit atomsPolar hydrogens only
FlexibilityNoneNoneTorsion tree of rotatable bonds
Extra dataNamed data fields per recordComment and other record typesREMARK lines
Table 2. SDF, MOL2 and PDBQT compared. PDBQT describes one ligand per input file; docking output files hold several poses. Sources: BIOVIA CTfile formats (2020), Tripos Mol2 format (2005), AutoDock 4.2.6 user guide.[2][8][9]

MOL2: atom types and partial charges

MOL2 comes from Tripos's SYBYL modeling software. A file is a series of sections, each opened by a record type indicator such as @<TRIPOS>MOLECULE, @<TRIPOS>ATOM or @<TRIPOS>BOND, and written in free format rather than fixed columns.[8]

Every atom line carries a SYBYL atom type and an optional partial charge. C.3 is an sp3 carbon, C.ar an aromatic carbon, N.am an amide nitrogen, N.4 a positively charged sp3 nitrogen, and O.co2 an oxygen in a carboxylate or phosphate group. Bonds can be typed am for amide and ar for aromatic as well as 1, 2 and 3.[8]

Those types suit programs that need force-field typing, and they are also MOL2's weakness as an exchange format. There is no formal-charge field, so a reader has to infer charges from types such as N.4 and O.co2, and has to turn ar and am bonds back into single and double bonds. Toolkits do not always make those inferences the same way. MOL2 to SMILES and SMILES to MOL2 convert between the two representations.

PDBQT: AutoDock types and a torsion tree

PDBQT is a PDB file with a partial charge (Q) and an AutoDock atom type (T) added to every atom line, plus keywords that describe flexibility.[9] The atom types encode hydrogen bonding rather than hybridization: C is an aliphatic carbon, A an aromatic carbon, OA an oxygen that accepts hydrogen bonds, N a nitrogen that does not, and HD a hydrogen that can be donated. Nonpolar hydrogens are removed and their charges merged into the carbons that carried them.[9]

Here is ethanol prepared by Meeko. Nine atoms in the SDF become four in the PDBQT, because the five hydrogens on carbon are merged away:

Text
REMARK SMILES CCO
REMARK SMILES IDX 1 1 2 2 3 3
REMARK H PARENT 3 4
ROOT
ATOM      1  C   UNL     1      -0.954   0.048   0.043  1.00  0.00     0.034 C 
ATOM      2  C   UNL     1       0.488  -0.322  -0.189  1.00  0.00     0.152 C 
ENDROOT
BRANCH   2   3
ATOM      3  O   UNL     1       1.277   0.325   0.738  1.00  0.00    -0.397 OA
ATOM      4  H   UNL     1       1.833   1.048   0.389  1.00  0.00     0.210 HD
ENDBRANCH   2   3
TORSDOF 1

Flexibility is written as a tree. The rigid core sits between ROOT and ENDROOT, each rotatable bond opens a BRANCH block holding the atoms it moves, branches can nest inside branches, and TORSDOF gives the number of rotatable bonds.[9] In ethanol the only branch is the carbon-oxygen bond that turns the hydroxyl hydrogen.

What PDBQT lacks is bonds. AutoDock neither reads nor writes CONECT records, so a program reading the file has to infer connectivity from distances, and bond orders are gone.[9] The charge column matters for AutoDock4's force field, but AutoDock Vina ignores user-supplied partial charges and handles electrostatic effects through its hydrophobic and hydrogen-bonding terms.[7]

Conversion pitfalls

Bond orders lost through PDB and PDBQT

Most damaged ligands have passed through a format without bond orders. The Vina documentation strongly advises against preparing small molecules from PDB files for exactly that reason: PDB does not carry the bond information that SDF does.[1] A program reading a ligand from PDB has to guess double bonds and aromaticity from bond lengths, and a slightly distorted crystal ligand or docked pose can come back with a wrong tautomer or a broken aromatic ring.

Converting SDF to PDB for a viewer is harmless; turning a PDB ligand back into SDF for chemistry is where the damage happens. PDBQT has the same gap, and Meeko works around it by writing the ligand's SMILES and an atom map into the REMARK lines shown above, then rebuilding the molecule from them on export.[1] The PDBQT to SDF converter relies on those remarks; a PDBQT written by older tools without them has its bond orders guessed.

Protonation and charge states

An SDF stores one charge state, whichever one its source chose. PubChem records acetic acid as the neutral acid. At pH 7.4 its carboxyl group, with a pKa near 4.8, is almost entirely ionized to acetate. Docked as the neutral acid, the ligand offers a hydrogen-bond donor it should not have and lacks the negative charge that could pair it with an arginine or lysine. The Vina FAQ lists incorrect protonation of the ligand or receptor among the usual causes of wrong results.[7]

Converters do not fix this on their own: adding hydrogens to a neutral SDF produces a neutral molecule with hydrogens. Dimorphite-DL enumerates the charge states expected across a pH range, turning acetic acid into acetate between pH 6.4 and 8.4. Open Babel, an open-source toolkit that reads and writes all three formats,[10] has a -p option that adds hydrogens appropriate for a given pH.[11] Generate 3D coordinates for the new state before docking.

2D records and missing hydrogens

A 2D record from PubChem or ChEMBL has to become 3D before docking, and the hydrogens added on the way need real positions. Open Babel's --gen3d option generates 3D coordinates and -h makes every hydrogen explicit.[11] When a file will not load at all, because of valence errors, unusual charges or several molecules in one record, Ligand fixer repairs and splits it.

Multi-record files

An SDF with 500 molecules is still one file, and tools differ in what they do with it. The SDF to PDBQT converter prepares every record separately and returns one PDBQT per molecule, since a PDBQT input holds a single ligand. DiffDock runs one docking job per record against the same receptor. When a downstream step needs a table rather than structures, SDF to SMILES turns each record into one canonical SMILES line.

SDF tools on ProteinIQ

To get structures, PubChem download and ChEMBL download return database SDFs, and SMILES to SDF builds 3D structures from SMILES with optional hydrogens and geometry relaxation.

To change formats, SDF to PDBQT prepares docking ligands with Meeko, PDBQT to SDF turns Vina poses back into chemistry, SDF to PDB writes HETATM records for viewers, and SDF to SMILES collapses each record to one line. Open Babel handles the remaining format pairs, including MOL2, along with hydrogens, pH protonation and 3D generation.

For docking itself, AutoDock Vina, GNINA and DiffDock all accept SDF ligands, and the molecular docking use case helps choose between them.

Frequently asked questions

What is the difference between a MOL file and an SDF file?

A MOL file holds one molecule and ends at M END. An SDF holds any number of molecules, each one a molfile optionally followed by named data fields and ended by a line of four dollar signs. A one-molecule SDF without data fields is a MOL file plus that final line.[2]

How do I open an SDF file?

Any text editor shows the contents, since SDF is plain text. To see the structure, open it in a molecular viewer such as PyMOL or ChimeraX, or in a cheminformatics toolkit such as RDKit or Open Babel. A 2D SDF will look flat in a 3D viewer because every z coordinate is zero.

Can an SDF file contain multiple molecules?

Yes. That is the main difference from a MOL file. Each record ends with a line of four dollar signs, and the next record starts on the following line. Database downloads such as ChEMBL's hold millions of records in one file.

Does an SDF file store charges?

It stores formal charges, in the atom block and in M CHG lines. It has no column for partial charges, so programs that need them either compute them on reading or store them in a data field, as PubChem does with MMFF94 charges in its 3D records.

How do I convert SDF to PDBQT?

Use a ligand preparation tool rather than a plain format converter, because PDBQT needs AutoDock atom types, partial charges and a torsion tree. The AutoDock Vina documentation uses Meeko for this, with mk_prepare_ligand.py -i ligand.sdf -o ligand.pdbqt.[1] The SDF to PDBQT converter runs the same preparation online. Start from a 3D SDF with the protonation state you intend to dock.

What does V2000 or V3000 at the end of line 4 mean?

It is the version of the connection table. V2000 uses fixed-width columns and is limited to 999 atoms and 999 bonds. V3000 uses tagged lines, has no such limit and supports enhanced stereochemistry.[2]