docs: def lattice_from_sites_file( site_file, cell_lengths ):
      """
      Generate a lattice from a sites file.
  
      Args:
          site_file (Str): Filename for the file containing the site information.
          cell_lengths (List(Float,Float,Float)): A list containing the [ x, y, z ] cell lengths.
  
      Returns:
          (Lattice): The new lattice
  
      Notes:
          | The site information file format is:
          |     <number_of_sites> (Int).
          | Followed by blocks of data separated by double linebreaks; one block per site.
          |     site: <site number> (Int).
          |     centre: <x> <y> <z> (Float,Float,Float).
          |     neighbours: <list of site numbers of neighbouring sites> (List[Int]).
          |     label: <site group labal> (Str).
          |     energy: <site occupation energy> (Float).
          | The energy is optional, and will be set to 0.0 if not included.
          | Line order within each block is not meaningful.
          | British and American English spellings for centre|center and neighbour|neighbor are accepted.
          | An example file can be found in the examples directory. 
      """
      sites = []
      site_re = re.compile( 'site:\s+([-+]?\d+)' )
      r_re = re.compile( 'cent(?:er|re):\s+([-\d\.e]+)\s+([-\d\.e]+)\s+([-\d\.e]+)' )
      r_neighbours = re.compile( 'neighbou{0,1}rs:((\s+[-+]?\d+)+)' )
      r_label = re.compile( 'label:\s+(\S+)' )
      r_energy = re.compile( 'energy:\s([-+\d\.]+)' )
      with open( site_file ) as f:
          filein = f.read().split("\n\n")
      number_of_sites = int( filein[0] )
      for i in range( number_of_sites ):
          block = filein[ i+1 ]
          number = int( site_re.findall( block )[0] )
          r = np.array( [ float(s) for s in r_re.findall( block )[0] ] )
          neighbours = [ int( s ) for s in r_neighbours.findall( block )[0][0].split() ]
          label = r_label.findall( block )[0]
          energy = r_energy.findall( block )
          if energy:
              energy = float( energy[0] )
          else:
              energy = 0.0
          sites.append( lattice_site.Site( number, r, neighbours, energy, label ) )
      return lattice.Lattice( sites, cell_lengths = np.array( cell_lengths ) )