code: def write(self, filename=None):
          
          if not filename:
              filename = self.filename
  
          # update time
          self.properties.CurrentDate = _current_time()
  
          # set rubber band to true
          self.properties.EnableRubberBand = 'true'
  
          # update start position
          self.update_start_position()
  
          # update well postions
          self.update_well_positions()
  
          # update counts
          self.update_counts()
  
          # remove py:pytype attributes
          objectify.deannotate(self.root)
  
          # remove namespaces added by lxml
          for child in self.root.iterchildren():
              etree.cleanup_namespaces(child)
  
          xml = etree.tostring(self.root, encoding='utf8',
                               xml_declaration=True, pretty_print=True)
  
          # fix format quirks
          # add carriage return character
          xml = u'\r\n'.join(l.decode(encoding='utf8') for l in xml.splitlines())
          # add space at "end/>" --> "end />"
          xml = re.sub(r'(["a-z])/>', r'\1 />', xml)
          xml = xml.replace("version='1.0' encoding='utf8'", 'version="1.0"')
  
          with open(filename, 'wb') as f:
              f.write(xml.encode('utf8'))
docs: Save template to xml. Before saving template will update
          date, start position, well positions, and counts.
  
          Parameters
          ----------
          filename : str
              If not set, XML will be written to self.filename.