• RE: Searching the database based on structure void space

    Hi Martin,

    There is no direct method in the API to search on spacegroup, so one has to fall back on enumeration of the database.  I believe the following will do what you want:

    import time

    from ccdc import io, utilities
    csd = io.EntryReader('csd')

    start = time.time()
    hits = []

    for i, e in enumerate(csd):
        if i and i % 1000 == 0:
            utilities.Timer.progress(start, i, len(csd), '%d hits' % len(hits))
        if not e.has_3d_structure:
        c = e.crystal
        if not c.spacegroup_symbol.startswith('R'):
        hits.append((c.void_volume(), e.identifier))


    This works by rejecting structures with no 3d information (they won't support a void volume calculation) and rejecting structures which do not have a rhombohdral space group.  If you like you can change this line to test different space groups.

    At the end you will have a list of void_volume, refcode pairs which you can write in any format you care.

    Hope this is helpful,

    Best wishes

  • RE: smiles search


    there is a workaround to this problem along the lines of:

    from ccdc import search

    smiles = 'something interesting'

    searcher = search.SubstructureSearch()
    hits = [h for h in searcher.search() if len(h.molecule.components) == 1 and h.molecule.smiles = smiles]

    Best wishes


  • RE: Filtering CSD for molecules with no disorder

    That's good to know, Puck. Feel free to raise any other issues you have with the API.

    Best wishes


  • RE: Filtering CSD for molecules with no disorder

    Hi Puck,

    there are a couple of issues with this script:

    Firstly, the no_disorder setting actually has three distinct values corresponding to False (don't check disorder at all), True (check for significant disorder, i.e of heavy atoms), or 'All' (check for any disorder).  Since you have specified True, structures like AARBOX will pass as the disorder is only in the position of the hydrogens.

    Secondly, you are checking the crystal for disorder, rather than the entry.  This is a less specific test than that of the entry, as the editorial decisions made for the entry are lost when constructing the crystal, and this is why ABABUB is found.

    There is a third problem for which I must apologise: there is a bug in the processing of the test for entries which, coincidentally I fixed today.  This will appear in the next release of the API.  This concerns entries with disorder but where the editors have not suppressed any atoms.

    A better check would be:

    for entry in io.EntryReader('csd'):
        if settings.test(entry) and not entry.has_disorder and len(entry.molecule.components) == 1:

    Please let me know how you get on with this.

    Best wishes


  • RE: unable to access coordinates

    Dear Gabor,

    I'm sorry to say you have come across a bug in the interaction between our licensing and our implementation.  The orth method has inadvertently taken its definition from a library with restrictions.  This will certainly be fixed in a forthcoming release, probably version 1.5.2 in about three months' time.

    In the meantime I have provided a 'monkey patch' which will change the use of 'orth' to one in a library without these restrictions.  This should be applied in any script you use to examine the coordinates of a molecule's atoms.

    Please let me know if anything is unclear about this, and my apologies for allowing this bug to slip into the release.

    Best wishes
    Richard Sykes


    # Monkey-patch around the licence restriction

    from ccdc.utilities import _private_importer
    with _private_importer():
        import ChemistryLib
        import PackingSimilarityLib
    PackingSimilarityLib.Point = ChemistryLib.Point


  • RE: Problem with atomic coordinates

    Hi Anna,

    this did come as a bit of a surprise to me, but after looking at it a bit I think I am clear as to how it happened.

    The symmetry operator returned by the  substructure search returns a composite of the unit cell translations and the underlying symmetry operator.  In this instance it represents the symmetry operator 1/3+y,2/3-x+y,2/3+z with a translation of (0, 0, 1).  When putting the translation component in to the operator we end up with 1 + 2/3 +z, which is rounded to 1.66667.  When applying the symetry operator to the crystal to create the symmetric_molecule, a check is made that the operator is one of the symmetry operators of the crystal, and 0.66667 is not exactly equal to 1/3.  

    The solution here is very simple: you can force the symmetry operator to be applied:

    >>> crystal = hits[0].crystal
    >>> symmop = hits[0].match_symmetry_operators()[-1]
    >>> symmetric_molecule = crystal.symmetric_molecule(symmop, force=True)

    I shall consider whether there may be a better representation of symmetry operators, with the translation kept separate from the operator for some future release.

    Thank you for raising this interesting case.

    Best wishes

  • RE: Problem with atomic coordinates

    Hi Anna,

    this occurs because the search is performed over the all molecules of the crystal as can be seen by inspecting the symmetry operators of the match:

    >>> print hits[0].match_symmetry_operators()[-1]

    The atoms provided by match_atoms() are of the single, central molecule of the crystal. I do think that this is not ideal, and I would like to provide some method for capturing the actually matched atoms in some future release.

    In the meantime you will can get the matched atoms in a rather roundabout way:

    >>> sym_copy = hits[0].crystal.symmetric_molecule(hits[0].match_symmetry_operators()[-1])
    >>> sym_Y = sym_copy.atom(Y.label)
    >>> print ccdc.descriptors.MolecularDescriptors.atom_distance (X, sym_Y)

    This will work as long as the atom labels of the molecule are distinct. If not the match will have to be done on the index of the atoms:

    >>> sym_Y = [a for a in sym_copy.atoms if a.index == Y.index][0]

    Best wishes



  • RE: conquest will not boot on Mac

    Dear Thomas,

    I think you may have put ConQuest as part of your startup system, so it gets started when you log in.  If this is the case, a colleague suggests starting your Mac in safe mode, then removing ConQuest from the startup folder.  You can then run ConQuest when you want to, rather than automatically when you log in.

    Please let me know if this works.

    Best wishes


  • RE: empty result for what seem a reasonable query

    Hi Pascal,

    I'm glad you've got it all sorted out.

    You'll be pleased to hear that the forthcoming release of the CSD (due later this month) will contain ADPs for many structures - around a quarter of them.  These will be accessible through the API as properties of the atoms of a molecule.

    Best wishes


  • RE: empty result for what seem a reasonable query

    Hi Pascal,

    I worked out the SMARTS pattern by hand, since I've had a reasonable amount of experience with Daylight SMARTS.  The best reference for it is:


    There is a sketcher which I believe will display SMARTS, though I've not used it:


    It appears to support setting variable atom and bond types.

    I'm afraid the CSD Python API does not support pickling of classes and instances.  Underneath the python is a set of bindings to native C++ objects and these cannot currently be serialised.  If I wish to save the results of a CSD search I will normally save the identifiers in a GCD file:

    with open('search_hits.gcd', 'w') as writer:
        writer.write('\n'.join(h.identifier for h in hits))

    Then if I wish to get the matching atoms, I will search the GCD file:

    hits = searcher.search('search_hits.gcd')

    Alternatively, you could use a CSV file, to record the identifier and atom numbers of each hit.

    Best wishes