def _read(self, filename=None, config=None, parse=True): "Reads and parses configuration input specified by kwds parameters" self.parser = QEParser(filename, config, self._type) #filename, config, type) (self.namelistRef, self.cardRef) = self.parser.setReferences() if parse and (filename or config): QEInput.parse(self) # Avoid calling method parse() from subclass self.qe = [self.header, self.namelists, self.cards, self.attach]
def __init__(self, filename=None, config=None, type='pw'): self.filename = filename self.config = config self.parser = QEParser(filename, config, type) self.type = type self.namelists = OrderedDict() self.cards = OrderedDict() self.attach = None # Specific for 'matdyn' self.namelistRef = None self.cardRef = None self.qe = [self.namelists, self.cards, self.attach]
def __init__(self, filename=None, config=None, type='pw'): self.header = None self.filename = filename self.config = config self.parser = QEParser(filename, config, type) self.type = type self.namelists = OrderedDict() self.cards = OrderedDict() self.attach = None # Specific for 'matdyn' self.namelistRef = None self.cardRef = None self.qe = [self.header, self.namelists, self.cards, self.attach]
def test_qeparser_type(self): # Type of configuration file recognizes specific namelists and card only! parser = QEParser(configText = fixtures.textHeader, type="pw") parser.parse() self.assertEqual(parser.toString(), '') # namelist 'INPUTPH' is not recognized
def test_qeparser_header(self): # Header for PH configuration files is mandatory parser = QEParser(configText = fixtures.textHeader, type="ph") parser.parse() self.assertEqual(parser.toString(), fixtures.assertHeader)
def test_qeparser_dynmat(self): # Slash and name of namelist on the same line with parameters parser = QEParser(configText=fixtures.textDynmat, type="dynmat") parser.parse() self.assertEqual(parser.toString(), fixtures.assertDynmat)
class QEInput(object): def __init__(self, filename=None, config=None, type='pw', parse=True): """ Initializes QEInput by passing either filename or config (not both) parameters filename: (str) -- Absolute or relative filename of file to be parsed config: (str) -- Configuration text to be parsed type: (str) -- Type of the simulation """ self.filename = filename self.config = config self._type = type.lower() self.filters = [] self.header = None self.namelists = OrderedDict() self.cards = OrderedDict() self.attach = None # Specific for 'matdyn', 'dynmat', etc. self.qe = None # DEPRICATED self.namelistRef = None self.cardRef = None self._read(filename, config, parse) def parse(self): """ Parses the configuration file and stores the values in qe dictionary """ (self.header, self.namelists, self.cards, self.attach) = self.parser.parse() def namelist(self, name): """ Returns namelist and adds to self.namelists. Return namelist if it exists. name: (str) -- Name of the new namelist """ # If namelist with the name exists, then return it name = name.lower() if self.namelistExists(name): return self.namelists[name] return self._createNamelist(name) def removeNamelist(self, name): """ Removes namelist if it exists or ignore otherwise name: (str) -- Name of the existing namelist """ name = name.lower() try: del(self.namelists[name]) except KeyError: # parameter is not present return def setNamelist(self, namelist): """ Sets/replaces namelist for self.namelists. It overwrites namelist if it exists already. So you this method with caution. namelist: (object: Namelist) -- Namelist object """ if not namelist: # No namelist, just ignore it! return self.namelists[namelist.name()] = namelist def namelistExists(self, name): """ Checks if namelist specified by name (lowered before) exists name: (str) -- Name of the namelist """ return self._exists(name, self.namelists.keys()) def setCard(self, card): """ Adds card to self.cards card: (object: Card) -- Card object """ if not card: return self.cards[card.name()] = card def removeCard(self, name): """ Remove card if it exists or ignore otherwise name: (str) -- Name of the existing card """ name = name.lower() try: del(self.cards[name]) except KeyError: # parameter is not present return # XXX: Make self.attach protected first! # def attach(self): # "Returns attachment" # return self.attach def addAttach(self, text): """ Sets attachment to text. If attachment is not None it still will be overwritten text: (str) -- Attachment text, usually is appended to the end of the configuration file """ self.attach = text def removeAttach(self): "Sets attachment to None" self.attach = None def card(self, name): """ Returns card specified by name if exists or create a new one """ name = name.lower() if self.cardExists(name): # If exists, return card return self.cards[name] return self._createCard(name) def cardExists(self, name): "Checks if card specified by name exists" return self._exists(name, self.cards.keys()) def getObject(self, name, dict): """ Returns object specified by name name: (str) -- Name that identifies an object through name() method dict: (dict) -- Dictionary that stores objects as {name: object} """ if not name or not dict: return None for n in dict.values(): if n.name() == name: return dict[name] return None def save(self, filename=None): """ Saves the QEInput structure to the configuration file filename: (str) -- File name where the configuration is stored to """ default = "config.out" if filename is None: if self.filename is not None: filename = self.filename else: filename = default f = open(filename, "w") f.write(self.toString()) f.close() def type(self): "Returns type of the configuration file" return self._type def applyFilter(self, filter, type=POSITIVE): """ Applies filter to the QEInput filter: (object: Filter) -- Filter that applies changes to QEInput """ if not filter: # No filter, just ignore it return None filter.apply(self, type) # Apply filter to QEInput self.filters.append(filter) def toString(self): """ Dumps QEInput structure to string """ s = '' if self.header: # Add header s += "%s\n" % self.header for name in self.namelistRef: # Add namelists nl = self.getObject(name, self.namelists) if nl is not None: s += nl.toString() for name in self.cardRef: # Add cards c = self.getObject(name, self.cards) if c is not None: s += c.toString() if self.attach: # Add attribute (e.g. for type='matdyn') s += self.attach return s def structure(self): """ Returns basic atomic structure information as list of tuples. Specific for 'pw' type Example: [('Ni', '52.98', 'Ni.pbe-nd-rrkjus.UPF'), (...)] """ # Extract structure not from pw type input. Hard to do it from other types if self._type != "pw": return None list = [] # list of structure card = self.card("atomic_species") for l in card.lines(): # Should have format: "<Label> <Mass> <Pseudo-Potential>" l = l.strip() if l == "": # Empty line continue list.append(l.split()) return list def readFile(self, filename): """ Reads and parses configuration input from file filename: (str) -- File name """ self.filename = filename self._read(filename=filename) def readString(self, config): """ Reads and parses configuration input from string config: (str) -- Configuration string """ self.config = config self._read(config=config) def _read(self, filename=None, config=None, parse=True): "Reads and parses configuration input specified by kwds parameters" self.parser = QEParser(filename, config, self._type) #filename, config, type) (self.namelistRef, self.cardRef) = self.parser.setReferences() if parse and (filename or config): QEInput.parse(self) # Avoid calling method parse() from subclass self.qe = [self.header, self.namelists, self.cards, self.attach] def _exists(self, name, list): "Checks if lowered name is in the list" if not name: return False name = name.lower() if name in list: return True return False def _createCard(self, name): """ Creates a new card name: (str) -- Name of the card """ if not name in self.cardRef: # If not standard card, ignore it return None card = Card(name) self.cards[name] = card return card def _createNamelist(self, name): """ Creates namelist specified by name name: (str) -- Name of the namelist """ if not name in self.namelistRef: # If not standard card, ignore it return None # Otherwise create a new namelist nl = Namelist(name) self.namelists[name] = nl return nl # DEPRICATED: Use namelist() instead def createNamelist(self, name): return namelist(name) # DEPRICATED: Use card() instead def createCard(self, name): return card(name) # DEPRICATED: Use setNamelist() instead def addNamelist(self, namelist): self.setNamelist(namelist) # DEPRICATED: Use setCard() instead def addCard(self, card): self.setCard(card)
def test_qeparser_comments(self): # Filters out comments parser = QEParser(filename="ph.mgb2.in", type="ph") parser.parse() self.assertEqual(parser.toString(), fixtures.assertMgB2)
def test_qeparser_type(self): # Type of configuration file recognizes specific namelists and card only! parser = QEParser(configText=fixtures.textHeader, type="pw") parser.parse() self.assertEqual(parser.toString(), '') # namelist 'INPUTPH' is not recognized
def test_qeparser_header(self): # Header for PH configuration files is mandatory parser = QEParser(configText=fixtures.textHeader, type="ph") parser.parse() self.assertEqual(parser.toString(), fixtures.assertHeader)
def test_qeparser_comma(self): # Parameters on the same line separated by comma - does not parse as it # should (intentionally) parser = QEParser(configText=fixtures.textComma, type="matdyn") parser.parse() self.assertEqual(parser.toString(), fixtures.assertComma)
def test_qeparser_card(self): # Card parser = QEParser(configText=fixtures.textCards) parser.parse() self.assertEqual(parser.toString(), fixtures.assertCards)
def test_qeparser_file(self): # Configuration file parser = QEParser(filename="ni.scf.in") parser.parse() self.assertEqual(parser.toString(), fixtures.assertFile)
def test_qeparser_comments(self): # Filters out comments parser = QEParser(filename = "ph.mgb2.in", type="ph") parser.parse() self.assertEqual(parser.toString(), fixtures.assertMgB2)
def test_qeparser_matdyn(self): # Attachment after card parser = QEParser(configText = fixtures.textMatdyn, type="matdyn") parser.parse() self.assertEqual(parser.toString(), fixtures.assertMatdyn)
def test_qeparser_dynmat(self): # Slash and name of namelist on the same line with parameters parser = QEParser(configText = fixtures.textDynmat, type="dynmat") parser.parse() self.assertEqual(parser.toString(), fixtures.assertDynmat)
class QEInput(object): """Quantum Espresso configuration class. It can: - Parse existing configuration file - Add, Edit or Remove parameters from/to namelist or card """ # Either filename or config (not both) can be specified def __init__(self, filename=None, config=None, type='pw'): self.header = None self.filename = filename self.config = config self.parser = QEParser(filename, config, type) self.type = type self.namelists = OrderedDict() self.cards = OrderedDict() self.attach = None # Specific for 'matdyn' self.namelistRef = None self.cardRef = None self.qe = [self.header, self.namelists, self.cards, self.attach] def parse(self): """ Parses the configuration file and stores the values in qe dictionary """ (self.header, self.namelists, self.cards, self.attach) = self.parser.parse() def createNamelist(self, name): """Creates namelist and adds to QEInput. """ nl = Namelist(name) self.namelists[name] = nl def addNamelist(self, namelist): """Adds namelist. """ self.namelists[namelist.name()] = namelist def removeNamelist(self, name): try: del(self.namelists[name]) except KeyError: # parameter is not present return def namelist(self, name): # Do I need editNamelist()? try: return self.namelists[name] except KeyError: # parameter is not present raise def createCard(self, name): """Creates card and adds to QEInput. """ self.cards[name] = Card(name) def addCard(self, card): """Adds card. """ self.cards[card.name()] = card def removeCard(self, name): try: del(self.cards[name]) except KeyError: # parameter is not present return def card(self, name): # Do I need editNamelist()? try: return self.cards[name] except KeyError: # parameter is not present raise def toString(self): (self.namelistRef, self.cardRef) = self.parser.setReferences() s = '' if self.header: # Add header s += self.header for name in self.namelistRef: # Add namelists nl = self.getObject(name, self.namelists) if nl is not None: s += nl.toString() for name in self.cardRef: # Add cards c = self.getObject(name, self.cards) if c is not None: s += c.toString() if self.attach: # Add attribute (e.g. for type='matdyn') s += self.attach return s def getObject(self, name, dict): """Returns object that corresponds to 'name'""" for n in dict.values(): if n.name() == name: return dict[name] return None def save(self, filename=None): """ Saves the QEInput to the configuration file""" default = "config.out" if filename is None: if self.filename is not None: filename = self.filename else: filename = default f = open(filename, "w") f.write(self.toString()) f.close() def type(self): return self.type
def test_qeparser_file(self): # Configuration file parser = QEParser(filename = "ni.scf.in") parser.parse() self.assertEqual(parser.toString(), fixtures.assertFile)
class QEInput(object): """Quantum Espresso configuration class. It can: - Parse existing configuration file - Add, Edit or Remove parameters from/to namelist or card """ # Either filename or config (not both) can be specified def __init__(self, filename=None, config=None, type='pw'): self.header = None self.filename = filename self.config = config self.parser = QEParser(filename, config, type) self.type = type self.namelists = OrderedDict() self.cards = OrderedDict() self.attach = None # Specific for 'matdyn', 'dynmat' self.namelistRef = None self.cardRef = None self.qe = [self.header, self.namelists, self.cards, self.attach] def parse(self): """ Parses the configuration file and stores the values in qe dictionary """ (self.header, self.namelists, self.cards, self.attach) = self.parser.parse() def createNamelist(self, name): """Creates namelist and adds to QEInput. """ nl = Namelist(name) self.namelists[name] = nl return nl def addNamelist(self, namelist): """Adds namelist. """ self.namelists[namelist.name()] = namelist def removeNamelist(self, name): try: del (self.namelists[name]) except KeyError: # parameter is not present return def namelist(self, name): "Returns namelist specified by name if exists or create a new one" if self.namelistExists(name): # If exists, return namelist return self.namelists[name] return self.createNamelist(name) # otherwise create a new one def namelistExists(self, name): "Checks if namelist specified by name exists" return self._exists(name, self.namelists.keys()) def createCard(self, name): "Creates card and adds to QEInput. " card = Card(name) self.cards[name] = card return card def addCard(self, card): "Adds card" self.cards[card.name()] = card def removeCard(self, name): try: del (self.cards[name]) except KeyError: # parameter is not present return def attach(self): "Returns attachment" return self.attach def addAttach(self, text): """ Sets attachment to some string. If attachment is not None it still will be overwritten """ self.attach = text def removeAttach(self): "Sets attachment to None" self.attach = None def card(self, name): "Returns card specified by name if exists or create a new one" if self.cardExists(name): # If exists, return card return self.cards[name] return self.createCard(name) def cardExists(self, name): "Checks if card specified by name exists" return self._exists(name, self.cards.keys()) def getObject(self, name, dict): """Returns object that corresponds to 'name'""" for n in dict.values(): if n.name() == name: return dict[name] return None def save(self, filename=None): """ Saves the QEInput to the configuration file""" default = "config.out" if filename is None: if self.filename is not None: filename = self.filename else: filename = default f = open(filename, "w") f.write(self.toString()) f.close() def type(self): return self.type def structure(self): """Returns basic structure information as list tuples Example: [('Ni', '52.98', 'Ni.pbe-nd-rrkjus.UPF'), (...)] """ # Hard to extract structure not from pw type input # TODO: Should also have "atomic_species" card if self.type != "pw": return None list = [] # list of structure card = self.card("atomic_species") for l in card.lines( ): # Should have format: "<Label> <Mass> <Pseudo-Potential>" l = l.strip() if l == "": # Empty line continue list.append(l.split()) return list def toString(self): (self.namelistRef, self.cardRef) = self.parser.setReferences() s = '' if self.header: # Add header s += "%s\n" % self.header for name in self.namelistRef: # Add namelists nl = self.getObject(name, self.namelists) if nl is not None: s += nl.toString() for name in self.cardRef: # Add cards c = self.getObject(name, self.cards) if c is not None: s += c.toString() if self.attach: # Add attribute (e.g. for type='matdyn') s += self.attach return s def _exists(self, name, list): if name in list: return True return False
def test_qeparser_card(self): # Card parser = QEParser(configText = fixtures.textCards) parser.parse() self.assertEqual(parser.toString(), fixtures.assertCards)
class QEInput(object): """Quantum Espresso configuration class. It can: - Parse existing configuration file - Add, Edit or Remove parameters from/to namelist or card """ # Either filename or config (not both) can be specified def __init__(self, filename=None, config=None, type='pw'): self.header = None self.filename = filename self.config = config self.parser = QEParser(filename, config, type) self.type = type self.namelists = OrderedDict() self.cards = OrderedDict() self.attach = None # Specific for 'matdyn' self.namelistRef = None self.cardRef = None self.qe = [self.header, self.namelists, self.cards, self.attach] def parse(self): """ Parses the configuration file and stores the values in qe dictionary """ (self.header, self.namelists, self.cards, self.attach) = self.parser.parse() def createNamelist(self, name): """Creates namelist and adds to QEInput. """ nl = Namelist(name) self.namelists[name] = nl def addNamelist(self, namelist): """Adds namelist. """ self.namelists[namelist.name()] = namelist def removeNamelist(self, name): try: del (self.namelists[name]) except KeyError: # parameter is not present return def namelist(self, name): # Do I need editNamelist()? try: return self.namelists[name] except KeyError: # parameter is not present raise def createCard(self, name): """Creates card and adds to QEInput. """ self.cards[name] = Card(name) def addCard(self, card): """Adds card. """ self.cards[card.name()] = card def removeCard(self, name): try: del (self.cards[name]) except KeyError: # parameter is not present return def card(self, name): # Do I need editNamelist()? try: return self.cards[name] except KeyError: # parameter is not present raise def toString(self): (self.namelistRef, self.cardRef) = self.parser.setReferences() s = '' if self.header: # Add header s += self.header for name in self.namelistRef: # Add namelists nl = self.getObject(name, self.namelists) if nl is not None: s += nl.toString() for name in self.cardRef: # Add cards c = self.getObject(name, self.cards) if c is not None: s += c.toString() if self.attach: # Add attribute (e.g. for type='matdyn') s += self.attach return s def getObject(self, name, dict): """Returns object that corresponds to 'name'""" for n in dict.values(): if n.name() == name: return dict[name] return None def save(self, filename=None): """ Saves the QEInput to the configuration file""" default = "config.out" if filename is None: if self.filename is not None: filename = self.filename else: filename = default f = open(filename, "w") f.write(self.toString()) f.close() def type(self): return self.type
def test_qeparser_comma(self): # Parameters on the same line separated by comma - does not parse as it # should (intentionally) parser = QEParser(configText = fixtures.textComma, type="matdyn") parser.parse() self.assertEqual(parser.toString(), fixtures.assertComma)
def test_qeparser_matdyn(self): # Attachment after card parser = QEParser(configText=fixtures.textMatdyn, type="matdyn") parser.parse() self.assertEqual(parser.toString(), fixtures.assertMatdyn)