diff --git a/CMakeLists.txt b/CMakeLists.txt
index cd028753ee9ac355e387072e00ab6c8505975efe..a8b1e2be2c6116ad29dd94363631012a3f551099 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 2.6.4 FATAL_ERROR)
 project(OpenStructure CXX C)
 set (OST_VERSION_MAJOR 1)
 set (OST_VERSION_MINOR 2)
-set (OST_VERSION_PATCH 3)
+set (OST_VERSION_PATCH 4)
 set (OST_VERSION_STRING ${OST_VERSION_MAJOR}.${OST_VERSION_MINOR}.${OST_VERSION_PATCH} )
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake_support)
 include(OST)
diff --git a/modules/index.rst b/modules/index.rst
index cb92f375dcdc0b20527f1bc26fec308465c4cc62..5f043a23855946ee43aa3077d84288ef59d5bd44 100644
--- a/modules/index.rst
+++ b/modules/index.rst
@@ -28,6 +28,7 @@ OpenStructure documentation
   external
   contributing
   table
+  mol/alg/lddt
 
 For Starters
 --------------------------------------------------------------------------------
@@ -99,6 +100,8 @@ Varia
 
 **Users** :doc:`Reporting a problem <users>`
 
+**lDDT** :doc:`lDDT command line executable<mol/alg/lddt>`
+
 Extending OpenStructure
 --------------------------------------------------------------------------------
 
diff --git a/modules/io/doc/mmcif.rst b/modules/io/doc/mmcif.rst
index 38934cc7943df2c6d1cec5f40dd43c34485368e6..018c662fc2a9b5f4ee6366c07e1dbbcdbb3af501 100644
--- a/modules/io/doc/mmcif.rst
+++ b/modules/io/doc/mmcif.rst
@@ -510,7 +510,7 @@ of the annotation available.
 
     See :attr:`operations`
 
-.. function:: PDBize(asu, seqres=None, min_polymer_size=10)
+.. function:: PDBize(asu, seqres=None, min_polymer_size=10, transformation=False)
 
     Returns the biological assembly (bio unit) for an entity. The new entity
     created is well suited to be saved as a PDB file. Therefore the function
@@ -525,6 +525,9 @@ of the annotation available.
       - ligands which resemble a polymer but have less than min_polymer_size
         residues are assigned the same numeric residue number. The residues are
         distinguished by insertion code.
+      - sometimes bio units exceed the coordinate system storable in a PDB file.
+        In that case, the box around the entity will be aligned to the lower
+        left corner of the coordinate system.
 
     Since this function is at the moment mainly used to create biounits from
     mmCIF files to be saved as PDBs, the function assumes that the
@@ -542,6 +545,9 @@ of the annotation available.
       get its own chain. Everything below that number will be sorted into the 
       ligand chain.
     :type min_polymer_size: int
+    :param transformation:  If set, return the transformation matrix used to
+      move the bounding box of the bio unit to the lower left corner.
+    :type transformation: :class:`bool`
 
 .. class:: MMCifInfoStructDetails
 
@@ -832,3 +838,5 @@ of the annotation available.
 ..  LocalWords:  SPRSDE pdb func autofunction exptl attr pdbx oper conf spr dif
 ..  LocalWords:  biounits biounit uniprot UNP seqs AddMMCifPDBChainTr cif asym
 ..  LocalWords:  auth GetMMCifPDBChainTr AddPDBCMMCifhainTr GetPDBMMCifChainTr
+..  LocalWords:  GetRevisions AddRevision SetRevisionsDateOriginal GetSize
+..  LocalWords:  GetNum num GetStatus GetLastDate GetFirstRelease storable
diff --git a/modules/io/pymod/__init__.py b/modules/io/pymod/__init__.py
index 71ea2ec6c2dcf829de2f6d6b90fa05450b4b844d..e9e597d726f5d921fb6938f12a13a221610b16b8 100644
--- a/modules/io/pymod/__init__.py
+++ b/modules/io/pymod/__init__.py
@@ -361,8 +361,10 @@ def LoadMMCIF(filename, restrict_chains="", fault_tolerant=None, calpha_only=Non
 # arguement is the usual 'self'.
 # documentation for this function was moved to mmcif.rst,
 # MMCifInfoBioUnit.PDBize, since this function is not included in SPHINX.
-def _PDBize(biounit, asu, seqres=None, min_polymer_size=10):
+def _PDBize(biounit, asu, seqres=None, min_polymer_size=10,
+            transformation=False):
   def _CopyAtoms(src_res, dst_res, edi, trans=geom.Mat4()):
+    atom_pos_wrong = False
     for atom in src_res.atoms:
       tmp_pos = geom.Vec4(atom.pos)
       new_atom=edi.InsertAtom(dst_res, atom.name, geom.Vec3(trans*tmp_pos), 
@@ -370,6 +372,12 @@ def _PDBize(biounit, asu, seqres=None, min_polymer_size=10):
                               occupancy=atom.occupancy, 
                               b_factor=atom.b_factor,
                               is_hetatm=atom.is_hetatom)
+      for p in range(0,3):
+        if new_atom.pos[p] <= -1000:
+          atom_pos_wrong = True
+        elif new_atom.pos[p] >= 10000:
+          atom_pos_wrong = True
+    return atom_pos_wrong
 
   chain_names='ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz'
   # create list of operations
@@ -409,6 +417,7 @@ def _PDBize(biounit, asu, seqres=None, min_polymer_size=10):
   cur_chain_name = 0
   water_chain = mol.ChainHandle()
   ligand_chain = mol.ChainHandle()
+  a_pos_wrong = False
   for tr in trans_matrices:
     # do a PDBize, add each new entity to the end product
     for chain in assu.chains:
@@ -430,7 +439,9 @@ def _PDBize(biounit, asu, seqres=None, min_polymer_size=10):
                                   chain.GetStringProp("pdb_auth_chain_name"))
         for res in chain.residues:
           new_res = edi.AppendResidue(new_chain, res.name, res.number)
-          _CopyAtoms(res, new_res, edi, tr)
+          a_b = _CopyAtoms(res, new_res, edi, tr)
+          if not a_pos_wrong:
+            a_pos_wrong = a_b
       elif chain.type == mol.CHAINTYPE_WATER:
         if not water_chain.IsValid():
           # water gets '-' as name
@@ -441,7 +452,9 @@ def _PDBize(biounit, asu, seqres=None, min_polymer_size=10):
           new_res = edi.AppendResidue(water_chain, res.name)
           new_res.SetStringProp('type', mol.StringFromChainType(chain.type))
           new_res.SetStringProp('description', chain.description)
-          _CopyAtoms(res, new_res, edi, tr)
+          a_b = _CopyAtoms(res, new_res, edi, tr)
+          if not a_pos_wrong:
+            a_pos_wrong = a_b
       else:
         if not ligand_chain.IsValid():
           # all ligands, put in one chain, are named '_'
@@ -463,8 +476,21 @@ def _PDBize(biounit, asu, seqres=None, min_polymer_size=10):
             new_res.SetStringProp("pdb_auth_chain_name",
                                   chain.GetStringProp("pdb_auth_chain_name"))
           ins_code = chr(ord(ins_code)+1)
-          _CopyAtoms(res, new_res, edi, tr)
+          a_b = _CopyAtoms(res, new_res, edi, tr)
+          if not a_pos_wrong:
+            a_pos_wrong = a_b
+  move_to_origin = None
+  if a_pos_wrong:
+    start = pdb_bu.bounds.min
+    move_to_origin = geom.Mat4(1,0,0,(-999 - start[0]),
+                               0,1,0,(-999 - start[1]),
+                               0,0,1,(-999 - start[2]),
+                               0,0,0,1)
+    edi = pdb_bu.EditXCS(mol.UNBUFFERED_EDIT)
+    edi.ApplyTransform(move_to_origin)
   conop.ConnectAll(pdb_bu)
+  if transformation:
+    return pdb_bu, move_to_origin
   return pdb_bu
 
 MMCifInfoBioUnit.PDBize = _PDBize
diff --git a/modules/io/tests/test_io_mmcif.py b/modules/io/tests/test_io_mmcif.py
index 94eb063301b5e56f697c7d67f43452c023b38f56..ba3eb6b63e008060e267f3fd8cb97ed838ac5b33 100644
--- a/modules/io/tests/test_io_mmcif.py
+++ b/modules/io/tests/test_io_mmcif.py
@@ -165,6 +165,21 @@ class TestMMCifInfo(unittest.TestCase):
     self.assertEquals(len(pdb_seqres_ent.GetChainList()[9].GetResidueList()),
                       414)
 
+  def test_mmcifinfo_biounit_pdbize_transformation(self):
+    ent, seqres, info = io.LoadMMCIF("testfiles/mmcif/3hqv.cif.gz",
+                                     seqres=True,
+                                     info=True)
+    pdb_ent, t = info.GetBioUnits()[0].PDBize(ent, transformation=True)
+    self.assertAlmostEquals(pdb_ent.GetCenterOfAtoms()[0], -915.759, 3)
+    self.assertAlmostEquals(pdb_ent.GetCenterOfAtoms()[1], -952.345, 2)
+    self.assertAlmostEquals(pdb_ent.GetCenterOfAtoms()[2], 3221.75, 2)
+    self.assertEquals(geom.Equal(t,
+                                 geom.Mat4(1,0,0,-920.462,
+                                           0,1,0,-966.654,
+                                           0,0,1,1703,
+                                           0,0,0,1),
+                                 epsilon=0.01), True)
+
   def test_mmcifinfo_structdetails(self):
     d = io.MMCifInfoStructDetails()
 
diff --git a/modules/io/tests/testfiles/mmcif/3hqv.cif.gz b/modules/io/tests/testfiles/mmcif/3hqv.cif.gz
new file mode 100644
index 0000000000000000000000000000000000000000..c7f6bcf78e4eef0b9b0e3f27b203263a2f7c56a7
Binary files /dev/null and b/modules/io/tests/testfiles/mmcif/3hqv.cif.gz differ
diff --git a/modules/mol/alg/doc/lddt.rst b/modules/mol/alg/doc/lddt.rst
new file mode 100644
index 0000000000000000000000000000000000000000..4e36560f4ff11b16c8585fb87856b9492627ce3c
--- /dev/null
+++ b/modules/mol/alg/doc/lddt.rst
@@ -0,0 +1,158 @@
+
+===========================
+How to use the lDDT program 
+===========================
+
+-----------
+Basic Usage
+-----------
+
+To calculate the lDDT for two PDB files (mdl1.pdb and mdl2.pdb) against the reference structure stored in ref.pdb, use the following command:
+
+.. code-block:: bash
+
+    lddt mdl1.pdb mdl2.pdb ref.pdb
+
+The local and global lDDT scores for each model are printed to the terminal.
+  
+--------------------
+Model Quality Checks
+--------------------
+
+When the lddt executable is called with the -f option, the program performs some 
+stereo-chemical and steric clashing checks before computing the lDDT scores. When 
+using this option, the user must also provide a text file containing average bond 
+lengths,angle widths and minimum clashing distances. lddt ships with a default 
+parameter file based on Engh and Huber parameters, and on the atomic radii as 
+defined in the Cambridge Structural Database. This file is human readable and can 
+be modified with a text editor. The location of the file must be passed to the 
+lddt executable using the -p parameter. 
+
+For example:
+
+.. code-block:: bash
+
+    lddt -f -p stereo_chemical_params.txt mdl1.pdb mdl2.pdb ref.pdb
+
+When the model quality checks are performed, the global and local lDDT scores are 
+preceded in the output text by some information on the outcome of the tests. The 
+number of serious stereo-chemical violations and steric-clashes in the structure 
+is reported, along with some statistics on the global model quality. The local and
+global lDDT scores are also adjusted according to the outcome of the tests.  When 
+stereochemical violations or steric clashes happen in the side-chain of a residue, 
+all distances involving atoms of that side-chain are automatically considered 
+non-conserved. When the violations involve backbone atoms of a residue, all 
+distances containing atoms of the residue are considered non-conserved. 
+
+
+-----------------------
+Custom Inclusion Radius
+-----------------------
+
+The lDDT score evaluates distances between atoms lying closer than a predermined 
+inclusion radius. By default the radius is set to 15 Angstroms, but the user can 
+override this value by passing a new one to the lddt executable through the -r 
+parameter (in Angstroms):
+
+For example:
+
+.. code-block:: bash
+
+    lddt -r 10.0 mdl1.pdb mdl2.pdb ref.pdb
+
+------------------
+Consistency Checks
+------------------
+
+When comparing structures, the lddt executable does not perform any chain name 
+checks. It only processes the first chain in each structure, irrespective of the 
+name. It does, however, perform a check on residue names, to make sure that the 
+structures are correctly aligned. The lddt executable will stop with an error if 
+the names of the residues being compared do not match. If the user needs for 
+specific reasons to override this behavior and skip the check, the lddt executable 
+can be called using the -x option. For example:
+
+For example:
+
+.. code-block:: bash
+
+    lddt -x mdl1.pdb mdl2.pdb ref.pdb
+
+-------------------------
+Custom Quality Parameters
+-------------------------
+
+The lddt executable uses several thresholds to determine how serious stereo-
+chemical violations and steric clashes are. For Bonds and Angles, the parameter 
+file contains typical average lengths and widths, together with expected standard 
+deviations for their measurements in protein structures. A violation is flagged as 
+serious by lDDT when the measured value deviates from the expected one by more 
+than a predefined number of standard deviations. By default this value is 12, but 
+the user can override the default tolerance thresholds using the -b and -a flags, 
+for bonds and angles respectively. 
+
+For steric clashes, the lddt executable recovers atomic radii and clashing 
+tolerance distances from the parameter file, depending on the atomic element under 
+investigation. When an atomic element cannot be determined, the lddt executable 
+uses a default atomic radius of 1.5 Angstrom. This value can be overriden using 
+the -m value, passing a new radius (in Ansgstroms) to the program.
+
+For example:
+
+.. code-block:: bash
+
+    lddt -f -p stereo_chemical_params.txt -b 8 -a 8 -m 1.0 mdl1.pdb ref.pdb
+
+
+
+-----------------------------
+Multiple Reference Structures
+-----------------------------
+
+lDDT allows the use of multiple reference structures at the same time (please see 
+the manuscript referenced above for details). In order to use multiple references, 
+simply add them to the first ref.pdb file, separated by a comma.  
+
+For example:
+
+.. code-block:: bash
+
+    lddt mdl1.pdb mdl2.pdb ref1.pdb,ref2.pdb,ref3.pdb
+
+----------------
+Output Verbosity
+----------------
+
+By default the lddt executable only outputs the values of the global and local 
+scores. However, users can tweak the verbosity of the output using the -v 
+parameters. The devault verbosity level is 0 (scores only). Other available 
+levels are: 1 (print information about non conserved distances and failed 
+quality checks, if performed) and 2 (print information on all distances and 
+all quality checks if performed)
+
+For example:
+
+.. code-block:: bash
+
+    lddt -v 1 -f -p stereo_chemical_params.txt mdl1.pdb mdl2.pdb ref.pdb
+
+WARNING: Verbosity levels 1 and 2 can generate a large amount of output text, 
+especially with large structures and multiple models being evaluated. 
+
+
+
+
+-------------
+Other Options
+-------------
+
+The lddt executable supports several other command line options. Some can be used 
+to select subsets of atoms in the input structures, others to exclude from the 
+calculation distances between residues that are too close in the amino-acid chain, 
+and many more. In order to see a complete list, just call the program without any 
+input parameters.
+
+.. code-block:: bash
+
+    lddt
+