Пример #1
0
 def __init__(self, filename=None, configText=None, type='pw'):
     self.namelists = OrderedDict()
     self.cards = OrderedDict()
     self.attach = None
     self.filename = filename
     self.configText = configText
     self.namelistRef = None
     self.cardRef = None
     self.type = type
Пример #2
0
 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]
Пример #3
0
 def __init__(self, qeConf):
     """the structure is initialized from PWSCF config file
        'lattice' and 'structure' are automatically updated"""
     self.filename = qeConf.filename
     self.atomicSpecies = OrderedDict()
     self.formatString = '%# .8f %# .8f %# .8f'
     # optConstraints three 1/0 for each coordinate of each atom
     self.optConstraints = []
     self.qeConf = qeConf
     self.lattice = QELattice()
     self.structure = Structure(lattice=self.lattice.diffpy())
     self.nat = None
     self.ntyp = None
Пример #4
0
 def setStructureFromQEInput(self):
     """ Loads structure from PWSCF config file"""
     self.atomicSpecies = OrderedDict()
     self.lattice.setLatticeFromPWInput(self.qeConf)
     #self.lattice = QELattice(qeConf = self.qeConf)
     self.structure = Structure(lattice = self.lattice.diffpy())
     self.nat = self.ntyp = None
     self.filename = self.qeConf.filename
     self.optConstraints = []
     
     if 'system' in self.qeConf.namelists:        
         self.nat  = int(self.qeConf.namelist('system').param('nat'))
         self.ntyp  = int(self.qeConf.namelist('system').param('ntyp'))
     if 'atomic_positions' in self.qeConf.cards:        
         atomicLines = self.qeConf.card('atomic_positions').lines()
         self.atomicPositionsType = self.qeConf.card('atomic_positions').arg()
         if self.atomicPositionsType == 'bohr' or self.atomicPositionsType == 'angstrom':
             raise NotImplementedError
         if self.atomicPositionsType == None:
             self.atomicPositionsType = 'alat'
         for line in atomicLines:
             if '!' not in line:
                 words = line.split()
                 coords = [float(w) for w in words[1:4]]
                 constraint = []
                 if len(words) > 4:
                     constraint = [int(c) for c in words[4:7]]
                 self.optConstraints.append(numpy.array(constraint, dtype = int))
                 atomSymbol = words[0]
                 if self.atomicPositionsType == 'alat':
                     coords = self.lattice.diffpy().fractional(numpy.array(coords[0:3])*self.lattice.a0)
                 if self.atomicPositionsType == 'crystal':
                     coords = numpy.array(coords[0:3])
                 self.structure.addNewAtom(atomSymbol, xyz = numpy.array(coords[0:3]))
     # parse mass ATOMIC_SPECIES section:
      
     if 'atomic_species' in self.qeConf.cards:
         atomicSpeciesLines = self.qeConf.card('atomic_species').lines()
         for line in atomicSpeciesLines:
             if '!' not in line:
                 if line.strip() != '':                            
                     atomicSpeciesWords = line.split()
                     element = atomicSpeciesWords[0]
                     mass = 0
                     ps = ''
                     if len(atomicSpeciesWords) > 1 :
                         mass = float(atomicSpeciesWords[1])
                     if len(atomicSpeciesWords) > 2:
                         ps = atomicSpeciesWords[2]
                     self.atomicSpecies[element] =  AtomicSpecies(element, mass, ps)
Пример #5
0
    def _get_atomicSpecies(self):
        atomicSpecies = OrderedDict()
        for a in self:
            atomicSpecies[a.element] = AtomicSpecies(element = a.element, \
                                        mass = a.mass, potential = a.potential)

        return atomicSpecies
    def __init__(self, filename=None, config=None, parse=True):
        self._filename = filename
        self._config = config
        # OrderedDict?
        # Header
        self._headerstr = ""  # Non-parsed header
        self._header = OrderedDict()  # Parsed header
        self._inputparams = OrderedDict()  # Dictionary of input parameters
        self._outputparams = OrderedDict()  # Dictionary of output parameters

        # Body
        self._sections = {}  # Sections
        self._defs = {}  # Definitions

        if parse and (self._fileExists() or config):
            self.parse()
Пример #7
0
    def _getCards(self, rawlist):
        cards       = OrderedDict()
        cardName    = None
        for l in rawlist:
            isCardName  = False
            p   = re.compile(CARD)
            m   = p.match(l)
            if m is not None:       # If card name matches
                firstPart   = m.group(1).lower()
                secondPart  = m.group(2).strip().lower()    # Catch argument of the card
                if firstPart in self.cardRef:
                    isCardName  = True
                    cardName    = firstPart
                    cards[cardName]    = {}

                    if (secondPart != ''):
                        cards[cardName]["args"] = secondPart
                    else:
                        cards[cardName]["args"] = None
                    cards[cardName]["values"]   = []

            if cardName is not None and not isCardName:
                cards[cardName]["values"].append(l)

        return cards
Пример #8
0
 def __init__(self, filename = None, configText = None, type = 'pw'):
     """
         filename:   (str) -- Absolute or relative filename of file to be parsed
         configText: (str) -- Configuration text to be parsed
         type:       (str) -- Type of the simulation
     """
     
     self.header     = None
     self.namelists  = OrderedDict()     # Namelist dictionary
     self.cards      = OrderedDict()     # Cards dictionary
     self.attach     = None
     self.filename   = filename
     self.configText = configText
     self.namelistRef    = None
     self.cardRef        = None
     self.type           = type.lower()
Пример #9
0
 def __init__(self, filename = None, configText = None, type = 'pw'):
     """
     Parameters:
         filename    -- absolute or relative filename to be parsed
         configText  -- configuration text to be parsed
         type        -- type of the simulation
     """
     
     self.header     = None
     self.namelists  = OrderedDict()     # Namelist dictionary
     self.cards      = OrderedDict()     # Cards dictionary
     self.attach     = None
     self.filename   = filename
     self.configText = configText
     self.namelistRef    = None
     self.cardRef        = None
     self.type           = type
Пример #10
0
def generate():
    inp     = open("pseudo.list")
    # Generate structure
    pseudo  = OrderedDict()
    str     = inp.read()
    pseudolist  = str.split()

    for name in pseudolist:
        l   = label(name)
        if l not in pseudo.keys(): # key does not exist
            pseudo[l]   = []

        pseudo[l].append(name)
     
    out    = open("pseudo.py", "w")
    out.write(toString(pseudo))
    inp.close()
    out.close()
    print "Done!"
Пример #11
0
def generate():
    inp = open("pseudo.list")
    # Generate structure
    pseudo = OrderedDict()
    str = inp.read()
    pseudolist = str.split()

    for name in pseudolist:
        l = label(name)
        if l not in pseudo.keys():  # key does not exist
            pseudo[l] = []

        pseudo[l].append(name)

    out = open("pseudo.py", "w")
    out.write(toString(pseudo))
    inp.close()
    out.close()
    print "Done!"
Пример #12
0
def returnError(metadataName, rootName, duration, message):
    metadatadict = OrderedDict([("duration", str(duration)),
                                ("error", message), ("idProperty", None),
                                ("successProperty", 'success'),
                                ("totalProperty", 'recordCount'),
                                ("success", False), ("recordCount", 0),
                                ("root", None), ("fields", None)])
    responsejson = json.dumps(dict([(metadataName, metadatadict),
                                    (rootName, None)]),
                              indent=1)
    return getJsonResponse(responsejson)
Пример #13
0
def getValuesForPoint(sceneid, x, y, crs):
    try:
        authenticate()
        lng, lat = utilities.getPointLL(x, y, crs)
        scene = ee.Image(sceneid)
        collection = ee.ImageCollection(scene)
        data = collection.getRegion(ee.Geometry.Point(lng, lat), 30).getInfo()
        if len(data) == 1:
            raise GoogleEarthEngineError("No values for point x:" + str(x) + " y: " + str(y) + " for sceneid: " + sceneid)
        return OrderedDict([(data[0][i], data[1][i]) for i in range (len(data[0]))])
    
    except (EEException, GoogleEarthEngineError):
        return "Google Earth Engine Error: " + str(sys.exc_info())        
Пример #14
0
    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)
Пример #15
0
    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)
Пример #16
0
 def __init__(self, qeConf):
     """the structure is initialized from PWSCF config file
        'lattice' and 'structure' are automatically updated"""
     self.filename = qeConf.filename
     self.atomicSpecies = OrderedDict()
     self.formatString = "%# .8f %# .8f %# .8f"
     # optConstraints three 1/0 for each coordinate of each atom
     self.optConstraints = []
     self.qeConf = qeConf
     self.lattice = QELattice()
     self.structure = Structure(lattice=self.lattice.diffpy())
     self.nat = None
     self.ntyp = None
Пример #17
0
    def _parseNamelists(self, text):
        namelists = OrderedDict()
        p = re.compile(COMMENT)
        s1 = re.sub(p, '', text)  # Remove comments
        p2 = re.compile(NAMELIST)
        matches = p2.findall(s1)  # Finds all namelist blocks
        for m in matches:
            name = m[0].lower()
            if name in self.namelistRef:
                params = self._parseParams(
                    m[1])  # Parse parameters from a namelist block
                namelists[name.lower()] = params

        self._convertNamelists(namelists)
Пример #18
0
    def _parseNamelists(self, text):
        """Parses text and populates namelist dictionary"""

        namelists   = OrderedDict()
        s1          = self._removeComments(text)
        p2          = re.compile(NAMELIST)
        matches     = p2.findall(s1)        # Finds all namelist blocks
        
        for m in matches:
            name    = m[0].lower()
            if name in self.namelistRef:
                params  = self._parseParams(m[1])     # Parse parameters from a namelist block
                namelists[name.lower()] = params

        self._convertNamelists(namelists)
Пример #19
0
 def __init__(self, qeConf):
     """the structure is initialized from PWSCF config file
        'lattice' and 'structure' are automatically updated"""
     self.filename = qeConf.filename
     self.atomicSpecies = OrderedDict()
     self.formatString = '%# .8f %# .8f %# .8f'
     # optConstraints three 1/0 for each coordinate of each atom
     self.optConstraints = []
     self.qeConf = qeConf
     #self.qeConf.parse()
     #self.setStructureFromQEInput()
     self.lattice = None
     self.structure = None
     self.nat = None
     self.ntyp = None
Пример #20
0
    def __init__(self, filename=None, config=None, parse=True):
        self._filename      = filename
        self._config        = config
        # OrderedDict?
        # Header 
        self._headerstr     = ""    # Non-parsed header
        self._header        = OrderedDict()    # Parsed header
        self._inputparams   = OrderedDict()    # Dictionary of input parameters
        self._outputparams  = OrderedDict()    # Dictionary of output parameters

        # Body
        self._sections      = {}    # Sections
        self._defs          = {}    # Definitions

        if parse and (self._fileExists() or config):
            self.parse()        
Пример #21
0
 def setStructureFromQEInput(self):
     """ Loads structure from PWSCF config file"""
     self.atomicSpecies = OrderedDict()
     self.lattice.setLatticeFromPWInput(self.qeConf)
     # self.lattice = QELattice(qeConf = self.qeConf)
     self.structure = Structure(lattice=self.lattice.diffpy())
     self.nat = int(self.qeConf.namelist("system").param("nat"))
     self.ntyp = int(self.qeConf.namelist("system").param("ntyp"))
     atomicLines = self.qeConf.card("atomic_positions").lines()
     self.atomicPositionsType = self.qeConf.card("atomic_positions").arg()
     if self.atomicPositionsType == "bohr" or self.atomicPositionsType == "angstrom":
         raise NotImplementedError
     if self.atomicPositionsType == None:
         self.atomicPositionsType = "alat"
     for line in atomicLines:
         if "!" not in line:
             words = line.split()
             coords = [float(w) for w in words[1:4]]
             constraint = []
             if len(words) > 4:
                 constraint = [int(c) for c in words[4:7]]
             self.optConstraints.append(numpy.array(constraint, dtype=int))
             atomSymbol = words[0]
             if self.atomicPositionsType == "alat":
                 coords = self.lattice.diffpy().fractional(numpy.array(coords[0:3]) * self.lattice.a0)
             if self.atomicPositionsType == "crystal":
                 coords = numpy.array(coords[0:3])
             self.structure.addNewAtom(atomSymbol, xyz=numpy.array(coords[0:3]))
             # parse mass ATOMIC_SPECIES section:
             atomicSpeciesLines = self.qeConf.card("atomic_species").lines()
             for line in atomicSpeciesLines:
                 if "!" not in line:
                     atomicSpeciesWords = line.split()
                     element = atomicSpeciesWords[0]
                     mass = float(atomicSpeciesWords[1])
                     ps = atomicSpeciesWords[2]
                     self.atomicSpecies[element] = AtomicSpecies(element, mass, ps)
Пример #22
0
 def __init__(self, name):
     """
         name: (str) -- Name of the namelist in lower case. Example: "control"
     """
     self._name = name.lower()  # keeps lower name
     self._params = OrderedDict()  # Replace dictionary by ordered dictionry
Пример #23
0
class Namelist():
    """Namelist class that corresponds to Namelist in QE config file"""

    def __init__(self, name):
        self.__name = name.lower() # keeps lower name
        self.params = OrderedDict() # Replace dictionary by ordered dictionry

    def name(self):
        return self.__name

    def setName(self, name):
        self.__name = name.lower()

    def param(self, param, quotes = True):
        """Returns value of parameter 'param'"""
        if self.__paramExists(param):
            if quotes:
                return self.params[param]
            else:
                return self._unquote(self.params[param])
            return self.params[param]

        return None

    def add(self, param, val, quotes = False):
        # Replaces addParam() Add verification?
        param = param.lower()
        if quotes:
            val     = self._quote(val)

        self.params[param]  = val


    def set(self, param, val, quotes = False):
        #  Replaces editParam() and addParam(). Merge with add()?
        """Edits parameter. If it doesn't exist, it just ignores it """
        if self.__paramExists(param):
            if quotes:
                val     = self._quote(val)

            self.params[param] = val

    def remove(self, param):
        """Deletes parameter"""
        if self.__paramExists(param):
            del(self.params[param])


    def exists(self,param):
        return self.__paramExists(param)


    def _quote(self, val):
        return "'" + val.strip('"').strip("'") + "'"


    def _unquote(self, val):
        return val.strip('"').strip("'")


    def toString(self, indent="    ", br="\n"):
        # Dump namelist
        # Should I use space?
        s = '&%s%s' % (self.name().upper(), br)

        for p in self.params.keys():
            s += '%s%s = %s,%s' % (indent, p, self.params[p], br)

        s += "/%s" % br
        return s


    def __paramExists(self, param):
        try:
            param = param.lower()
            self.params[param]
            return True
        except KeyError:    # parameter is not present
            return False


    # Depricated methods:
    # Depricated
    def addParam(self, param, val):
        self.add(param, val)

    # Depricated
    def editParam(self, param, val):
        self.set(param, val)

    # Depricated
    def removeParam(self, param):
        self.remove()
Пример #24
0
 def __init__(self, name):
     """
         name: (str) -- Name of the namelist in lower case. Example: "control"
     """
     self._name      = name.lower()  # keeps lower name
     self._params    = OrderedDict() # Replace dictionary by ordered dictionry
Пример #25
0
class Namelist(Block):
    
    def __init__(self, name):
        """
            name: (str) -- Name of the namelist in lower case. Example: "control"
        """
        self._name      = name.lower()  # keeps lower name
        self._params    = OrderedDict() # Replace dictionary by ordered dictionry


    def get(self, param, quotes = True):
        """
        Returns paramater value. If no parameter exists, return None.
        When quotes=True quotes are not added to parameter's value.

            param: (str) -- Parameter of the namelist
            quotes: (bool) -- True - if add quotes '' to parameters value,
                              False - otherwise

        Note: replaces param()
        """
        if not self._paramExists(param):
            return None

        param   = param.lower()
        if quotes:
            return self._params[param]
        
        return self._unquote(self._params[param])


    def set(self, param, val, quotes = False):
        """
        Sets existing parameter to the specified value.
        If no parameter exists, create one
        
            param: (str) -- Parameter name
            val: (str) -- Parameter value
            quotes: (bool) -- Add quotes to the value or not
        """
        param   = param.lower()
        if quotes:
            val     = self._quote(val)

        self._params[param] = val


    # TODO: Rename to params() in the future
    def paramlist(self):
        """
        Returns list of parameter names
        """
        return self._params.keys()


    def remove(self, param):
        """
        Deletes parameter

            param: (str) -- Name of the parameter
        """
        if self._paramExists(param):
            del(self._params[param])


    def exists(self,param):
        """
        Checks if parameter exists in the namelist

            param: (str) -- Name of the parameter
        """
        return self._paramExists(param)


    def _quote(self, val):
        """
        Quotes value with "'" quote mark

            val: (str) -- Value to be quoted
        """
        return "'" + val.strip('"').strip("'") + "'"
    
    
    def _unquote(self, val):
        """
        Removes quotes "'" (unquotes) on both sides of the string

            val: (str) -- Value to be unquoted
        """
        return val.strip('"').strip("'")


    def toString(self, indent = 4, br = "\n"):
        """
        Dumps namelist as a sting
        
            indent: (int) -- Number of spaces in indent for parameters
            br: (str) -- Separator between parameters
        """
        ind  = ""
        for i in range(indent):    # Populate indent
            ind += " "

        s = '&%s%s' % (self.name().upper(), br)

        for p in self._params.keys():
            s += '%s%s = %s,%s' % (ind, p, self._params[p], br)

        s += "/%s" % br 
        return s


    def _paramExists(self, param):
        """
        Checks if parameter exists in self._params

            param: (str) -- Name of the parameter
        """
        try:
            param = param.lower()
            self._params[param]
            return True
        except KeyError:    # parameter is not present
            return False


    # DEPRICATED METHODS:
    # DEPRICATED: Use get() instead
    def param(self, param, quotes = True):
        return self.get(param, quotes)

    # DEPRICATED: Use set() instead!
    def add(self, param, val, quotes = False):
        self.set(param, val, quotes)

    # DEPRICATED: Use set() instead!
    def editParam(self, param, val):
        self.set(param, val)

    # DEPRICATED: Use set() instead!
    def addParam(self, param, val):
        self.add(param, val)

    # DEPRICATED: Use remove() instead!
    def removeParam(self, param):
        self.remove(param)
Пример #26
0
class QEStructure():
    
    def __init__(self, qeConf):
        """the structure is initialized from PWSCF config file
           'lattice' and 'structure' are automatically updated"""
        self.filename = qeConf.filename
        self.atomicSpecies = OrderedDict()
        self.formatString = '%# .8f %# .8f %# .8f'
        # optConstraints three 1/0 for each coordinate of each atom
        self.optConstraints = []
        self.qeConf = qeConf
        self.lattice = QELattice()
        self.structure = Structure(lattice = self.lattice.diffpy())
        self.nat = None
        self.ntyp = None
        self.atomicPositionsType = 'crystal'       
        

    def atomLabels(self):
        labels = []
        for l in self.atomicSpecies:
            labels.append(l)
        return labels
        
    def parseInput(self):
        self.setStructureFromQEInput()
        
    def parseOutput(self, pwscfOutputFile):
        self.setStructureFromPWOutput(pwscfOutputFile)

    def setStructureFromPWOutput(self, pwscfOutputFile): 
        """
        Loads structure from PWSCF output file. If there was geometry
        optimization (relax or vc-relax), the structure will be reinitialized
        from the last step of the optimization
        """
        file = open(pwscfOutputFile)
        pwscfOut = file.readlines()
        pseudoList = []
        atomList = []
        massList = []
        self.atomicSpecies = OrderedDict()
        self.atomicPositionsType = 'alat'  
        # parse beginning:
        for i, line in enumerate(pwscfOut):
            if 'lattice parameter (a_0)' in line:
                a_0 = float(line.split()[4])
            if 'bravais-lattice index' in line:
                ibrav = int(line.split('=')[1])
            if 'number of atoms/cell' in line:
                self.nat = int(line.split('=')[1])
            if 'number of atomic types' in line:
                self.ntyp = int(line.split('=')[1])
            if 'PseudoPot.' in line:
                pseudoList.append(line.split('read from file')[1].strip())
            if 'atomic species   valence    mass     pseudopotential' in line:
                for j in range(self.ntyp):
                    atomList.append(pwscfOut[i+j+1].split()[0])
                    massList.append(float(pwscfOut[i+j+1].split()[2]))
            if 'crystal axes: (cart. coord. in units of a_0)' in line:
                latticeVectors = [[float(f)*a_0 for f in pwscfOut[i + 1].split()[3:6] ],
                                  [float(f)*a_0 for f in pwscfOut[i + 2].split()[3:6] ],
                                  [float(f)*a_0 for f in pwscfOut[i + 3].split()[3:6] ]]
                self.lattice.setLatticeFromQEVectors(ibrav, latticeVectors)
            if 'site n.     atom                  positions (a_0 units)' in line:
                self.structure = Structure(lattice = self.lattice.diffpy())
                for n in range(self.nat):
                    words = pwscfOut[i + n + 1].split()
                    atomSymbol = words[1]
                    coords = [float(w) for w in words[6:9]]
                    constraint = []
                    self.optConstraints.append(numpy.array(constraint, dtype = int))
                    #print numpy.array(coords[0:3])*a_0
                    coords = self.lattice.diffpy().fractional(numpy.array(coords[0:3])*a_0)
                    self.structure.addNewAtom(atomSymbol, xyz = numpy.array(coords[0:3]))

        for a, m, p in zip(atomList, massList, pseudoList):
            self.atomicSpecies[a] = AtomicSpecies(a, m, p)

        #print 'Input structure from output file: ', self.toString()
        #Parse end:
        # Find all geometry optimization steps
        posList =  [i for i,line in enumerate(pwscfOut) if '!    total energy' in line]
        lastSection = pwscfOut[posList[-1]:]
        for i, line in enumerate(lastSection):
            if 'CELL_PARAMETERS (alat)' in line:
                latticeVectors = [[float(f)*a_0 for f in lastSection[i + 1].split() ],
                                  [float(f)*a_0 for f in lastSection[i + 2].split() ],
                                  [float(f)*a_0 for f in lastSection[i + 3].split() ]]
                self.lattice.setLatticeFromQEVectors(ibrav, latticeVectors)
                #self.lattice = QELattice(ibrav = ibrav, base = latticeVectors)
                #print self.lattice.diffpy().base
            if 'ATOMIC_POSITIONS (alat)' in line:
                self.structure = Structure(lattice = self.lattice.diffpy())
                for n in range(self.nat):
                    words = lastSection[i + n + 1].split()
                    atomSymbol = words[0]
                    coords = [float(w) for w in words[1:4]]
                    constraint = []
                    if len(words) > 4:
                        constraint = [int(c) for c in words[4:7]]
                    self.optConstraints.append(numpy.array(constraint, dtype = int))
                    coords = self.lattice.diffpy().fractional(numpy.array(coords[0:3])*a_0)
                    self.structure.addNewAtom(atomSymbol, xyz = numpy.array(coords[0:3]))
    
    
    def setStructureFromQEInput(self):
        """ Loads structure from PWSCF config file"""
        self.atomicSpecies = OrderedDict()
        self.lattice.setLatticeFromPWInput(self.qeConf)
        #self.lattice = QELattice(qeConf = self.qeConf)
        self.structure = Structure(lattice = self.lattice.diffpy())
        self.nat = self.ntyp = None
        self.filename = self.qeConf.filename
        self.optConstraints = []
        
        if 'system' in self.qeConf.namelists:        
            self.nat  = int(self.qeConf.namelist('system').param('nat'))
            self.ntyp  = int(self.qeConf.namelist('system').param('ntyp'))
        if 'atomic_positions' in self.qeConf.cards:        
            atomicLines = self.qeConf.card('atomic_positions').lines()
            self.atomicPositionsType = self.qeConf.card('atomic_positions').arg()
            if self.atomicPositionsType == 'bohr' or self.atomicPositionsType == 'angstrom':
                raise NotImplementedError
            if self.atomicPositionsType == None:
                self.atomicPositionsType = 'alat'
            for line in atomicLines:
                if '!' not in line:
                    words = line.split()
                    coords = [float(w) for w in words[1:4]]
                    constraint = []
                    if len(words) > 4:
                        constraint = [int(c) for c in words[4:7]]
                    self.optConstraints.append(numpy.array(constraint, dtype = int))
                    atomSymbol = words[0]
                    if self.atomicPositionsType == 'alat':
                        coords = self.lattice.diffpy().fractional(numpy.array(coords[0:3])*self.lattice.a0)
                    if self.atomicPositionsType == 'crystal':
                        coords = numpy.array(coords[0:3])
                    self.structure.addNewAtom(atomSymbol, xyz = numpy.array(coords[0:3]))
        # parse mass ATOMIC_SPECIES section:
         
        if 'atomic_species' in self.qeConf.cards:
            atomicSpeciesLines = self.qeConf.card('atomic_species').lines()
            for line in atomicSpeciesLines:
                if '!' not in line:
                    if line.strip() != '':                            
                        atomicSpeciesWords = line.split()
                        element = atomicSpeciesWords[0]
                        mass = 0
                        ps = ''
                        if len(atomicSpeciesWords) > 1 :
                            mass = float(atomicSpeciesWords[1])
                        if len(atomicSpeciesWords) > 2:
                            ps = atomicSpeciesWords[2]
                        self.atomicSpecies[element] =  AtomicSpecies(element, mass, ps)


    def load(self, source, **args):
        task = {
            'diffpy': self.setStructureFromDiffpyStructure
        }
        if source == 'diffpy':
            if 'ibrav' in args and args['ibrav'] != 0:
                task['diffpy'] = self.setReducedStructureFromDiffpyStructure

        task[source](**args)
        
        self.updatePWInput(qeConf = self.qeConf)


    def setStructureFromDiffpyStructure(self, structure, massList = [], psList = [], ibrav = 0):
        """
        structure - diffpy.Structure object
        ibrav - Lattice index
        psList - list of strings with pseudopotential names
        diffpyStructure object will be modified with reduced atomic positions
        """      
        diffpyLattice = structure.lattice
        
        self.structure = structure
               
        
        #set lattice and  convert to bohr units
        qeLattice = QELattice(ibrav = 0, a = 1.889725989, base = diffpyLattice.base)
        
        
        self.lattice = qeLattice
        self.lattice.type = 'generic cubic'

        atomNames = []
        for a in structure:
            if self._element(a) not in atomNames:
                atomNames.append(self._element(a))
        
        #print atomNames
        #print len(massList)
        for i, elem in enumerate(atomNames):
            if len(massList) - 1 < i:
                mass = 0
            else:
                mass = massList[i]
            if len(psList) - 1 < i:
                ps = ''
            else:
                ps = psList[i]               
            self.atomicSpecies[elem] =  AtomicSpecies(elem, mass, ps)
        
        for atom in structure:
            self.optConstraints.append([])        
        
        # for i, atom in enumerate(structure):
            # elem = self._element(atom)
            # if len(massList) - 1 < i:
                # mass = 0
            # else:
                # mass = massList[i]
            # if len(psList) - 1 < i:
                # ps = ''
            # else:
                # ps = psList[i]
            # self.atomicSpecies[elem] =  AtomicSpecies(elem, mass, ps)
            # self.optConstraints.append([])

#        for atom, mass, ps in zip(structure, massList, psList):
#            elem = self._element(atom)
#            self.atomicSpecies[elem] =  AtomicSpecies(elem, mass, ps)
#            self.optConstraints.append([])

        self.nat = len(structure)
        self.ntyp = len(self.atomicSpecies)        
     
                        
    def setReducedStructureFromDiffpyStructure(self, structure, ibrav, massList = [], psList = []):
        """
        structure - diffpy.Structure object
        ibrav - Lattice index
        psList - list of strings with pseudopotential names
        diffpyStructure object will be modified with reduced atomic positions
        """

        #self.atomicSpecies = OrderedDict()
        #self.optConstraints = []
        #self.atomicPositionsType = 'crystal'

        diffpyLattice = structure.lattice

        a = diffpyLattice.a
        b = diffpyLattice.b
        c = diffpyLattice.c
        cAB = cosd(diffpyLattice.gamma)
        cBC = cosd(diffpyLattice.alpha)
        cAC = cosd(diffpyLattice.beta)

        qeLattice = QELattice(ibrav = ibrav, a = a, b = b, c = c,  cBC =  cBC, \
                              cAC = cAC, cAB = cAB)

        self.lattice = qeLattice
        # make a deep copy (does not wok now)
        #reducedStructure = Structure(diffpyStructure)
        reducedStructure = structure

        reducedStructure.placeInLattice(Lattice(base=qeLattice.diffpy().base))

        # collect atoms that are at equivalent position to some previous atom
        duplicates = set([a1
            for i0, a0 in enumerate(reducedStructure) for a1 in reducedStructure[i0+1:]
                if   self._element(a0) == self._element(a1) and equalPositions(a0.xyz, a1.xyz, eps=1e-4)])

        
        # Filter out duplicate atoms.  Use slice assignment so that
        # reducedStructure is not replaced with a list.
        reducedStructure[:] = [a for a in reducedStructure if not a in duplicates]

        self.structure = reducedStructure

        atomNames = []
        for a in reducedStructure:
            if self._element(a) not in atomNames:
                atomNames.append(self._element(a))
        
        #print atomNames
        #print len(massList)
        for i, elem in enumerate(atomNames):
            if len(massList) - 1 < i:
                mass = 0
            else:
                mass = massList[i]
            if len(psList) - 1 < i:
                ps = ''
            else:
                ps = psList[i]      
            #print mass, ps
            # atomDict[a] = 
        # for i, atom in enumerate(reducedStructure):
            # elem = self._element(atom)
            # if len(massList) - 1 < i:
                # mass = 0
            # else:
                # mass = massList[i]
            # if len(psList) - 1 < i:
                # ps = ''
            # else:
                # ps = psList[i]            
            self.atomicSpecies[elem] =  AtomicSpecies(elem, mass, ps)
        
        for atom in reducedStructure:
            self.optConstraints.append([])

        # convert to bohr units
        self.lattice.setLattice(ibrav, self.lattice.a*1.889725989, \
                                 self.lattice.b*1.889725989,
                                 self.lattice.c*1.889725989)

        self.nat = len(reducedStructure)
        self.ntyp = len(self.atomicSpecies)

        # use rstrip to avoid duplicate line feed
        #print reducedStructure.writeStr(format='discus').rstrip()
        #print reducedStructure.writeStr(format='discus')
        #print reducedStructure.writeStr().rstrip()
        #print reducedStructure
        #self.lattice = setLatticeFromDiffpyLattice(structure.lattice, ibrav)


    # def toString(self):
        # s = self.lattice.toString() + '\n'
        # if self.atomicPositionsType == 'alat':
            # s = s + 'Atomic positions in units of lattice parametr "a":\n'        
        # if self.atomicPositionsType == 'crystal':
            # s = s + 'Atomic positions in crystal coordinates:\n'
        # for atom, constraint in zip(self.structure, self.optConstraints):
            # if self.atomicPositionsType == 'alat':      
                # coords = self.lattice.diffpy().cartesian(atom.xyz)/self.lattice.a
                # coords = self.formatString%(coords[0], coords[1], coords[2])
            # else:
                # if self.atomicPositionsType == 'crystal':
                    # coords = self.formatString%(atom.xyz[0], atom.xyz[1], atom.xyz[2])
                # else:
                    # raise NonImplementedError
            # s = s + '%-3s'%self._element(atom) + '    ' + coords + '  ' \
                    # + str(constraint)[1:-1] + '\n'

        # s = s + '\n'
        # for element, specie in self.atomicSpecies.items():
            # s = s + specie.toString() + '\n'

        # return s

    def toString(self, string = None):
        if string != None:
            string = self.lattice.toString(string = string)
            qeConf = QEInput(config = string)
            qeConf.parse()
        else:
            if self.qeConf != None:
                qeConf = self.qeConf
            else:
                qeConf = QEInput(config = '')

        self.updatePWInput(qeConf)
        return qeConf.toString()

        
    def updatePWInput(self, qeConf = None):

        if qeConf == None:
            qeConf = self.qeConf

        self.lattice.updatePWInput(qeConf)

        if 'system' not in qeConf.namelists:
            qeConf.addNamelist('system')            
        qeConf.namelist('system').remove('ntyp')
        qeConf.namelist('system').remove('nat')
        if self.ntyp != None:
            qeConf.namelist('system').add('ntyp', self.ntyp)
        if self.nat != None:
            qeConf.namelist('system').add('nat', self.nat)
        
        if len(qeConf.namelist('system').params) == 0:
            qeConf.removeNamelist('system')  

        if 'atomic_positions' in qeConf.cards:
            qeConf.removeCard('atomic_positions')
        qeConf.createCard('atomic_positions')
        qeConf.card('atomic_positions').setArg(self.atomicPositionsType)
        for atom, constraint in zip(self.structure, self.optConstraints):
            if self.atomicPositionsType == 'alat':
                coords = self.lattice.diffpy().cartesian(atom.xyz)/self.lattice.a
                coords = self.formatString%(coords[0], coords[1], coords[2])
            else:
                if self.atomicPositionsType == 'crystal':
                    coords = self.formatString%(atom.xyz[0], atom.xyz[1], atom.xyz[2])
                else:
                    raise NonImplementedError
            line = '%-3s'%self._element(atom) + '    ' + coords + '  ' + str(constraint)[1:-1]
            qeConf.card('atomic_positions').addLine(line)
        
        if len(qeConf.card('atomic_positions').lines()) == 0:
            qeConf.removeCard('atomic_positions')

        # update ATOMIC_SPECIES card
        if 'atomic_species' in qeConf.cards:
            qeConf.removeCard('atomic_species')
        qeConf.createCard('atomic_species')
        for element, specie in self.atomicSpecies.items():
            qeConf.card('atomic_species').addLine(specie.toString())
        
        if len(qeConf.card('atomic_species').lines()) == 0:
            qeConf.removeCard('atomic_species')        


    def save(self, fname = None):
        """Writes/updates structure into PW config file,
           if the file does not exist, new one will be created"""
        filename = fname
        if fname != None:
            self.lattice.save(filename)
            qeConf = QEInput(fname)
            qeConf.parse()
        else:
            filename = self.filename
            self.lattice.save(filename)
            qeConf = self.qeConf
            
        self.updatePWInput(qeConf)
        qeConf.save(filename)

        

    def diffpy(self):
        return self.structure


    def _element(self, atom):
        """
        Is needed for suport both diffpy and matter classess
        """
        if 'element' in dir(atom):
            return atom.element
        else:
            if 'symbol' in dir(atom):
                return atom.symbol
            else:
                raise
Пример #27
0
def getQueryStringParams(querystring):
    return OrderedDict([(q.split("=")[0], urllib.unquote(q.split("=")[1]))
                        for q in querystring.split("&")])
Пример #28
0
class QEParser:
    """
    Flexible Parser for Quantum Espresso (QE) configuration files. It parses the file specified
    by filename or configuration string and stores parameters in namelists, cards and
    attachment (specific for matdyn) data structures that later on can be used in
    parameters' manipulations
    """
    def __init__(self, filename=None, configText=None, type='pw'):
        self.namelists = OrderedDict()
        self.cards = OrderedDict()
        self.attach = None
        self.filename = filename
        self.configText = configText
        self.namelistRef = None
        self.cardRef = None
        self.type = type

    def parse(self):
        self.getReferences()

        if self.configText is not None:  # First try use configText
            text = self.configText
        elif self.filename is not None:  # ... then from file
            text = self._getText(self.filename)
        else:
            raise NameError('Dude, set config text or filename')  # Compalain

        self._parseNamelists(text)
        self._parseCards(text)
        return (self.namelists, self.cards, self.attach)

    def toString(self):
        for n in self.namelists.keys():
            print self.namelists[n].toString()

        for c in self.cards.keys():
            print self.cards[c].toString()

        if self.attach:
            print self.attach

    def getReferences(self):
        input = "input%s" % self.type
        module = _import("inputs.%s" % input)
        self.namelistRef = getattr(module, "namelists")
        self.cardRef = getattr(module, "cards")
        return (self.namelistRef, self.cardRef)

    def _parseNamelists(self, text):
        namelists = OrderedDict()
        p = re.compile(COMMENT)
        s1 = re.sub(p, '', text)  # Remove comments
        p2 = re.compile(NAMELIST)
        matches = p2.findall(s1)  # Finds all namelist blocks
        for m in matches:
            name = m[0].lower()
            if name in self.namelistRef:
                params = self._parseParams(
                    m[1])  # Parse parameters from a namelist block
                namelists[name.lower()] = params

        self._convertNamelists(namelists)

    # Converts from dictionary to Namelist
    def _convertNamelists(self, namelists):
        for name in namelists.keys():
            nl = Namelist(name)
            for p in namelists[name]:
                nl.add(p[0], p[1])

            self.namelists[name] = nl

    # Parses parameters
    def _parseParams(self, text):
        params = []
        p = re.compile(EXPRESSION)  # Match expression
        matches = p.findall(text)
        for m in matches:
            pl = self._getParams(m)  # Parameters list
            params.append(pl)

        return params

    def _getParams(self, text):
        """ Takes string like 'a = 2' and returns tuple ('a', 2) """
        s = text.split('=')
        for i in range(len(s)):
            s[i] = s[i].strip()

        param = s[0]
        val = s[1]
        # Assume that there are two values only: (variable, value) pair
        assert len(s) == 2

        return (param, val)

    def _parseCards(self, text):
        p = re.compile(COMMENT)
        s1 = re.sub(p, '', text)  # Remove comments
        p2 = re.compile(NAMELIST)
        s2 = re.sub(p2, '', s1)  # Remove namelists

        # Special case for 'matdyn'
        if self.type == 'matdyn':
            self.attach = s2.strip()
            return

        rawlist = []

        p = re.compile(EMPTY_LINE)
        s = s2.split('\n')
        for line in s:
            line = line.strip()
            if line != '':
                rawlist.append(
                    line
                )  # rawlist contains both cardnames and card lines in order

        self._convertCards(self._getCards(rawlist))

    def _getCards(self, rawlist):
        cards = OrderedDict()
        cardName = None
        for l in rawlist:
            isCardName = False
            p = re.compile(CARD)
            m = p.match(l)
            if m is not None:  # If card name matches
                firstPart = m.group(1).lower()
                secondPart = m.group(
                    2).strip().lower()  # Catch argument of the card
                if firstPart in self.cardRef:
                    isCardName = True
                    cardName = firstPart
                    cards[cardName] = {}

                    if (secondPart != ''):
                        cards[cardName]["args"] = secondPart
                    else:
                        cards[cardName]["args"] = None
                    cards[cardName]["values"] = []

            if cardName is not None and not isCardName:
                cards[cardName]["values"].append(l)

        return cards

    def _convertCards(self, cards):
        for cname in cards.keys():
            c = Card(cname)
            c.setArg(cards[cname]["args"])
            for l in cards[cname]["values"]:
                c.addLine(l)

            self.cards[cname] = c

    def _getText(self, filename):
        try:
            f = open(filename)
        except IOError:
            print "I/O error"
        except:
            import sys
            print "Unexpected error:", sys.exc_info()[0]
            raise

        text = f.read()
        f.close()

        return text
Пример #29
0
class QEParser:
    """
    Flexible Parser for Quantum Espresso (QE) configuration files.
    
    It parses the file specified by filename or configuration string and stores
    parameters in namelists, cards and attachment data
    structures that later on can be used in parameters' manipulations
    """
    
    def __init__(self, filename = None, configText = None, type = 'pw'):
        """
        Parameters:
            filename    -- absolute or relative filename to be parsed
            configText  -- configuration text to be parsed
            type        -- type of the simulation
        """
        
        self.header     = None
        self.namelists  = OrderedDict()     # Namelist dictionary
        self.cards      = OrderedDict()     # Cards dictionary
        self.attach     = None
        self.filename   = filename
        self.configText = configText
        self.namelistRef    = None
        self.cardRef        = None
        self.type           = type


    def parse(self):
        """Parses string and returns namelists, cards, attachment and header"""
        self.setReferences()

        if self.configText is not None: # First try use configText
            text = self.configText
        elif self.filename is not None: # ... then from file
            text = self._getText(self.filename)
        else:
            raise NameError('Dude, set config text or filename')  # Compalain

        self._parseHeader(text)
        self._parseNamelists(text)
        self._parseAttach(text)
        self._parseCards(text)
        
        return (self.header, self.namelists, self.cards, self.attach)


    def toString(self):
        """Returns string of parsed values"""
        
        s   = ''
        if self.header:
            s   += self.header

        for n in self.namelists.keys():
            s   += self.namelists[n].toString()

        for c in self.cards.keys():
            s   += self.cards[c].toString()

        if self.attach:
            s   += self.attach

        return s


    def setReferences(self):
        """Sets reference names for namelists and cards for specified simulation type"""
        
        input   = "input%s" % self.type
        module  = _import("inputs.%s" % input)
        self.namelistRef   = getattr(module, "namelists")
        self.cardRef       = getattr(module, "cards")

        return (self.namelistRef, self.cardRef)
    

    def _parseHeader(self, text):
        """Cuts the first line if it header"""
        start   = self._namelistStart(text)
        if start is not None and start == 0:
            return  # There is no header 

        lines   = text.splitlines(True)
        if lines:
            self.header   = lines[0]


    def _parseNamelists(self, text):
        """Parses text and populates namelist dictionary"""

        namelists   = OrderedDict()
        s1          = self._removeComments(text)
        p2          = re.compile(NAMELIST)
        matches     = p2.findall(s1)        # Finds all namelist blocks
        
        for m in matches:
            name    = m[0].lower()
            if name in self.namelistRef:
                params  = self._parseParams(m[1])     # Parse parameters from a namelist block
                namelists[name.lower()] = params

        self._convertNamelists(namelists)


    def _removeComments(self, text):
        """Removes comments from the text"""
        p   = re.compile(COMMENT)
        s   = re.sub(p, '', text)
        return self._removeEmptyLines(s)
        

    def _convertNamelists(self, namelists):
        """Converts dictionary to Namelist"""
        for name in namelists.keys():
            nl      = Namelist(name)
            for p in namelists[name]:
                nl.add(p[0], p[1])
                
            self.namelists[name] = nl


    def _parseParams(self, text):
        """Parses parameters"""
        params  = []
        p       = re.compile(EXPRESSION)        # Match expression
        matches = p.findall(text)
        for m in matches:
            pl  = self._getParams(m)         # Parameters list
            params.append(pl)

        return params


    def _getParams(self, text):
        """ Takes string like 'a = 2' and returns tuple ('a', 2) """
        s = text.split('=')
        for i in range(len(s)):
            s[i] = s[i].strip()

        param   = s[0]
        val     = s[1]
        # Assume that there are two values only: (variable, value) pair
        assert len(s) == 2

        return (param, val)


    def _parseAttach(self, text):
        """Special case for simulations that have attachments"""

        if self.type in ATTACHSIM:
            self.attach = self._cutNamelistText(text)


    def _parseCards(self, text):
        """Parses text and populates cards dictionary"""
        if self.type in ATTACHSIM:  # There should not be cards for simulations with attachment
            return

        s   = self._cutNamelistText(text)
        self._convertCards(self._getCards(self._rawlist(s) ))


    def _cutNamelistText(self, text):
        """Cuts the namelist text"""
        
        s       = self._removeComments(text)
        end     = self._namelistEnd(s)

        if end is not None:
            s   = s[end + 1:]  # Suppose that cards and attachmet starts with new line

        return s


    def _rawlist(self, text):
        """Removes empty lines or lines with white spaces only"""
        rawlist = []

        s   = text.splitlines(True)
        for line in s:
            stripped    = line.strip()
            if stripped != '':
                rawlist.append(line)    # rawlist contains both cardnames and card lines in order

        return rawlist


    def _removeEmptyLines(self, text):
        """Joins non empty lines or lines with white spaces only in the list to one string"""
        return ''.join(self._rawlist(text))


    def _getCards(self, rawlist):
        cards       = OrderedDict()
        cardName    = None
        for l in rawlist:
            isCardName  = False
            p   = re.compile(CARD)
            m   = p.match(l)
            if m is not None:       # If card name matches
                firstPart   = m.group(1).lower()
                secondPart  = m.group(2).strip().lower()    # Catch argument of the card
                if firstPart in self.cardRef:
                    isCardName  = True
                    cardName    = firstPart
                    cards[cardName]    = {}

                    if (secondPart != ''):
                        cards[cardName]["args"] = secondPart
                    else:
                        cards[cardName]["args"] = None
                    cards[cardName]["values"]   = []

            if cardName is not None and not isCardName:
                cards[cardName]["values"].append(l)

        return cards


    def _convertCards(self, cards):
        for cname in cards.keys():
            c   = Card(cname)
            c.setArg(cards[cname]["args"])
            for l in cards[cname]["values"]:
                c.addLine(l)

            self.cards[cname]    = c


    def _namelistStart(self, text):
        """Returns the start character position of the first namelist in the text"""
        s           = self._removeComments(text)
        p           = re.compile(NAMELIST)
        matches     = p.finditer(s)        # Finds all namelist blocks
        starts      = []

        for m in matches:
            starts.append(m.start())

        if len(starts):
            return starts[0]    # Get first value

        return None


    def _namelistEnd(self, text):
        """
        Returns the end character position of the last namelist in the text
        Notes:
            - text should be clear from comments (filtered by _removeComments(text)),
              otherwise the end character of the last namelist will be incorrect
        """
        s           = self._removeComments(text)

        p           = re.compile(NAMELIST)
        matches     = p.finditer(s)        # Finds all namelist blocks
        ends      = []

        for m in matches:
            ends.append(m.end())

        size    = len(ends)
        if size:
            return ends[size-1]    # Get last position value

        return None


    def _getText(self, filename):
        try:
            f = open(filename)
        except IOError:
            print "I/O error"
        except:
            import sys
            print "Unexpected error:", sys.exc_info()[0]
            raise

        text       = f.read()
        f.close()

        return text
Пример #30
0
class McStasComponentParser(object):

    def __init__(self, filename=None, config=None, parse=True):
        self._filename      = filename
        self._config        = config
        # OrderedDict?
        # Header 
        self._headerstr     = ""    # Non-parsed header
        self._header        = OrderedDict()    # Parsed header
        self._inputparams   = OrderedDict()    # Dictionary of input parameters
        self._outputparams  = OrderedDict()    # Dictionary of output parameters

        # Body
        self._sections      = {}    # Sections
        self._defs          = {}    # Definitions

        if parse and (self._fileExists() or config):
            self.parse()        


    def parse(self):
        """
        Parses data from config string or file and populates header structure
        """
        configText  = self._configText()
        bodyText    = self._parseHeader(configText) # Parse header
        self._parseBody(bodyText)


    def header(self):
        "Returns header"
        return self._header


    def sections(self):
        "Returns sections"
        return self._sections


    def definitions(self):
        "Returns definitions"
        return self._defs


    def inputparams(self):
        "Returns input parameters"
        return self._inputparams

        
    def outputparams(self):
        "Returns output parameters"
        return self._outputparams


    def toString(self, br="\n"):
        str     = ""
        for (key, value) in self._header.iteritems():
            str += "%s: %s%s" % (key, value, br)

        str += br
        for (key, value) in self._sections.iteritems():
            str += "%s: %s%s" % (key, value, br)

        str += br
        for (key, value) in self._defs.iteritems():
            str += "%s: %s%s" % (key, value, br)

        return str


    def _parseHeader(self, origText):
        "Parses header and populates header dictionary"
        p           = re.compile(COMMENT, re.DOTALL)
        matches     = p.findall(origText)
        if len(matches) < 1: # No header found
            return origText

        m           = matches[0]                # First comment is the header
        self._headerstr = m
        text        = self._strip(WINCR, m)     # Strip carriage return
        headertext  = self._strip(STAR, text)   # Strip stars

        # Extract sections from headertext (hide them?)
        info        = self._sectionText(INFO_SEC, headertext)
        desc        = self._sectionText(DESC_SEC, headertext)
        param       = self._sectionText(PARAM_SEC, headertext)

        self._parseCompName(headertext)
        self._parseInfoSection(info)
        self._parseDescSection(desc)
        self._parseParamSection(param)

        # Find end position of the header
        end     = self._headerEnd(origText)

        return origText[end:]


    def _parseBody(self, bodyText):
        "Parses body and populates body dictionary"
        bodytext        = self._cleanupText(bodyText)

        self._parseDefComp(bodytext)
        self._parseDefParams(bodytext)
        self._parseSetParams(bodytext)
        self._parseOutParams(bodytext)
        self._parseStateParams(bodytext)
        self._parsePolParams(bodytext)
        self._parseBodySections(bodytext)


    def _cleanupText(self, text):
        "Cleans up text"
        temptext    = self._strip(WINCR, text)          # Strip carriage return
        temptext    = self._strip(COMMENT, temptext)    # Strip C comments (/*...*/)
        # Don't strip C++ comments as it make Jiao's hack die :)
        #temptext    = self._strip(CPP_COMMENT, temptext)# Strip C++ comments (//...)

        return temptext


    def _parseDefComp(self, text):
        "Parses Define Component"
        name        = ""
        value       = self._defValues(DEF_COMP, text)
        if value:
            name    = value

        self._defs["name"]  = name


    def _parseDefParams(self, text):
        "Parses and sets arameters"
        self._setDefParams(DEF_PARAMS, text, "definition_parameters")
        


    def _setDefParams(self, regex, text, paramname):
        "Parses and parameters and"
        params   = []
        value       = self._defValues(regex, text)
        if value:
            params    = self._defParams(value)

        self._defs[paramname]  = params


    def _defParams(self, line):
        "Returns definition parameters as dictionary"
        # Format: [<type>]{spaces}<variable>{spaces}[={spaces}<value>]
        # Example: line    = "string XX, string  YY =1, ZZ , WW= 2"
        params  = []
        items   = line.strip(" ()\n").split(",")
        for it in items:
            var     = it.strip()
            # Doesn't work well
            #match   = self._defValues(PARAM_VAR, var, None)

            match   = self._paramMatch(var)
            assert len(match) == 3
            if match[1] == "":  # If name is empty, return empty list
                return []
            param           = {}
            param["type"]   = match[0]
            param["name"]   = match[1]
            param["value"]  = match[2]
            params.append(param)
        
        return params


    def _paramMatch(self, var):
        """
        Returns tuple: (<type>, <name>, <value>).
        Example: ("string", "filename", "'IE.dat'")
        """
        type    = ""
        name    = ""
        value   = ""
        if not var:
            return (type, name, value)
        parts   = var.split("=")
        if len(parts) == 2:
            value   = parts[1].strip()      # Get value if it exists
            value   = value.strip("\"'")    # Strip quotation marks?

        # Catching pointer variable
        parts2  = parts[0].split("*")   
        if len(parts2) == 2:    
            type    = "%s *" % parts2[0].strip()
            name    = parts2[1].strip()
            return (type, name, value)

        # Catching non-pointer variable
        varparts    = parts[0].split()
        if len(varparts) == 2:
            type    = varparts[0].strip()
            name    = varparts[1].strip()
        elif len(varparts) == 1:
            name    = varparts[0].strip()

        return (type, name, value)


    def _parseSetParams(self, text):
        "Parses Setting Parameters"
        self._setDefParams(SET_PARAMS, text, "setting_parameters")


    def _parseOutParams(self, text):
        "Parses Output Parameters"
        self._setDefParams(OUT_PARAMS, text, "output_parameters")


    def _parseStateParams(self, text):
        "Parses State Parameters"
        self._setListParams(STATE_PARAMS, text, "state_parameters")


    def _parsePolParams(self, text):
        "Parses Polarization Parameters"
        self._setListParams(POL_PARAMS, text, "polarization_parameters")


    def _setListParams(self, regex, text, paramname):
        "Parses text and populates list parameters in defintion part"
        params   = []
        value       = self._defValues(regex, text)
        if value:
            items   = value.strip(" ()").split(",") # Strip brackets just in case
            for it in items:    # clean up params
                params.append(it.strip())

        self._defs[paramname]  = params


    def _defValues(self, regex, text, flags=re.DOTALL|re.IGNORECASE|re.MULTILINE):
        "Returns matches for regex pattern. Used mostly for definitions"
        p           = re.compile(regex)
        if flags:
            p       = re.compile(regex, flags)
        matches     = p.findall(text)
        if len(matches) < 1: # No value found
            return None

        m           = matches[0]
        if type(m) is str:
            return m.strip()    # If value is string, strip spaces

        return m    # otherwise return as they are
        

    def _parseBodySections(self, text):
        "Parse body sections"
        for secname in BODY_SECTIONS:
            p           = re.compile(sectionRegex(secname), re.DOTALL|re.IGNORECASE)
            matches     = p.findall(text)
            secname     = secname.lower()   # Turn section name lower case
            if secname == FINALLY.lower():  # Special case for "FINALLY" section
                secname = "finalize"

            if len(matches) < 1:            # No section found
                self._sections[secname] = ""
                continue

            mm      = matches[0]
            if len(mm) != 2:                # Section content is empty
                self._sections[secname] = ""
                continue

            self._sections[secname]  = mm[1]


    def _configText(self):
        "Take config from file if it exist and readable, or use from config - otherwise"
        configText  = ""
        if self._fileExists():
            try:        # Try to read it
                configText  = open(self._filename).read()
            except:
                pass    # No exception
            return configText

        if self._config:
            configText  = self._config

        return configText   # Empty string


    def _fileExists(self):
        "Checks if file exists"
        if self._filename and os.path.exists(self._filename):
            return True

        return False


    def _strip(self, regex, text):
        "Strips piece of text that matches regex pattern"
        p   = re.compile(regex, re.DOTALL|re.MULTILINE)
        s   = re.sub(p, '', text)
        return s


    def _parseCompName(self, text):
        p           = re.compile(COMP_NAME, re.IGNORECASE)
        namefinds   = p.findall(text)
        if not namefinds:
            return ""    # Empty name
        
        compname    = namefinds[0].strip()
        self._header["componentname"]    = compname        


    # XXX: integrate with _defValue()
    def _sectionText(self, secregex, text, flags=re.DOTALL):
        "Returns section string that matches secregex pattern"
        p       = re.compile(secregex)
        if flags:
            p       = re.compile(secregex, flags)
        matches     = p.findall(text)
        if len(matches) < 1: # No section found, return empty string
            return ""
        
        return matches[0]   # Return the first found match


    # XXX: Merge with _populateParams()
    def _parseInfoSection(self, text):
        "Parses info section and populates part of header parameters"
        # XXX: There might be problems that description has ':' character
        #           In this case check if numbr == 2 and afterparam = True
        lines       = text.split("\n")

        for l in lines:
            l   = l.strip()
            if l == '':
                continue    # Skip empty line

            p   = re.compile(PARAM)
            m   = p.match(l)
            
            if m:
                param       = m.group(1).strip()
                value       = m.group(2).strip()
                paramname   = self._paramName(param)
                if not paramname:
                    continue
                    
                paramname   = paramname.lower()
                self._header[paramname] = value
            else:
                self._header["simple_description"]    = l                
            

    def _paramName(self, param):
        """
        Returns parameter name.
        Note: Only those parameter which are in INFO_PARAMS will be returned
        """
        # Non standard parameter
        if self._isMatch(COPYRIGHT_N, param):
            return "copyright"

        # Standard parameters
        for regex in STD_PARAMS:
            if self._isMatch(regex, param):
                return param

        return None


    def _isMatch(self, regex, text):
        "Returns True if matches, False - otherwise"
        p       = re.compile(regex, re.IGNORECASE)
        m       = p.match(text)
        if m:
            return True # There is the match

        return False


    def _parseDescSection(self, text):
        "Parses description section and populates part of header parameters"
        # Find example
        p           = re.compile(EXAMPLE, re.DOTALL|re.IGNORECASE)
        matches     = p.findall(text)
        example     = ""        # Default value
        if len(matches) >= 1:   # No section found, return empty string
            mstr = matches[0]   # Take first match!
            if mstr:
                example  = " ".join(mstr.strip(" \n").split("\n"))

        self._header["example"]    = example

        # Get full description: strip example and take whatever is left
        text        = self._strip(EXAMPLE, text)
        self._header["full_description"]    = text.strip()


    def _parseParamSection(self, text):
        "Parses parameter section and populates input and output parameters of header"
        # Get output parameters first!
        outputtext      = self._sectionText(OUTPUT_PARAMS, text, flags=re.DOTALL|re.IGNORECASE)
        filteredtext    = self._strip(OUTPUT_PARAMS, text)

        # ... and then input parameters
        inputtext       = self._sectionText(INPUT_PARAMS, filteredtext, flags=re.DOTALL|re.IGNORECASE)

        self._parseInputSubsection(inputtext)
        self._parseOutputSubsection(outputtext)


    def _parseInputSubsection(self, text):
        "Parses input text and populates input parameters"
        self._inputparams  = self._populateParams(IOPARAM, text)
        self._header["input_parameters"]    = self._inputparams


    def _parseOutputSubsection(self, text):
        "Parses output text and populates output parameters"
        self._outputparams  = self._populateParams(IOPARAM, text)
        self._header["output_parameters"]   = self._outputparams


    def _populateParams(self, paramregex, text):
        "Populates dictionary of parameters"
        params      = {}
        lines       = text.split("\n")

        for l in lines:
            l   = l.strip()
            if l == '':
                continue    # Skip empty line

            p   = re.compile(paramregex)
            m   = p.match(l)

            if m:
                (param, value)  = (m.group(1).strip(), m.group(2).strip())
                # XXX: What if value has '\n'?
                if not param:
                    continue
                    
                params[param]   = value

        return params


    def _headerEnd(self, origText):
        "Returns end position of the header"
        p           = re.compile(COMMENT, re.DOTALL)
        ss          = p.search(origText)
        return ss.end()
Пример #31
0
class Namelist():
    """Namelist class that corresponds to Namelist in QE config file"""
    def __init__(self, name):
        self.__name = name.lower()  # keeps lower name
        self.params = OrderedDict()  # Replace dictionary by ordered dictionry

    def name(self):
        return self.__name

    def setName(self, name):
        self.__name = name.lower()

    def param(self, param):
        """Returns value of parameter 'param'"""
        if self.__paramExists(param):
            return self.params[param]

    def add(self, param, val):
        # Replaces addParam() Add verification?
        param = param.lower()
        self.params[param] = val

    def set(self, param, val):
        #  Replaces editParam() and addParam(). Merge with add()?
        """Edits parameter. If it doesn't exist, it just ignores it """
        if self.__paramExists(param):
            self.params[param] = val

    def remove(self, param):
        """Deletes parameter"""
        if self.__paramExists(param):
            del (self.params[param])

    def __paramExists(self, param):
        try:
            param = param.lower()
            self.params[param]
            return True
        except KeyError:  # parameter is not present
            return False

    def toString(self, indent="    ", br="\n"):
        # Dump namelist
        # Should I use space?
        s = '&%s%s' % (self.name().upper(), br)

        for p in self.params.keys():
            s += '%s%s = %s,%s' % (indent, p, self.params[p], br)

        s += "/%s" % br
        return s

    # Depricated methods:
    # Depricated
    def addParam(self, param, val):
        self.add(param, val)

    # Depricated
    def editParam(self, param, val):
        self.set(param, val)

    # Depricated
    def removeParam(self, param):
        self.remove()
Пример #32
0
#!/usr/bin/env python
# Autogenerated script by pseudo-generator.py
from orderedDict import OrderedDict

PSEUDO = OrderedDict()
PSEUDO["Ag"] = (
    "Ag.pbe-d-rrkjus.UPF",
    "Ag.pz-d-rrkjus.UPF",
)

PSEUDO["Al"] = (
    "Al.blyp-n-van_ak.UPF",
    "Al.bp-n-van_ak.UPF",
    "Al.pbe-n-van.UPF",
    "Al.pbe-rrkj.UPF",
    "Al.pbe-sp-van.UPF",
    "Al.pw91-n-van.UPF",
    "Al.pz-vbc.UPF",
)

PSEUDO["Ar"] = ("Ar.pz-rrkj.UPF", )

PSEUDO["As"] = (
    "As.pbe-n-van.UPF",
    "As.pw91-n-van.UPF",
    "As.pz-bhs.UPF",
)

PSEUDO["Au"] = (
    "Au.blyp-van_ak.UPF",
    "Au.bp-van_ak.UPF",
Пример #33
0
class Namelist(Block):
    def __init__(self, name):
        """
            name: (str) -- Name of the namelist in lower case. Example: "control"
        """
        self._name = name.lower()  # keeps lower name
        self._params = OrderedDict()  # Replace dictionary by ordered dictionry

    def get(self, param, quotes=True):
        """
        Returns paramater value. If no parameter exists, return None.
        When quotes=True quotes are not added to parameter's value.

            param: (str) -- Parameter of the namelist
            quotes: (bool) -- True - if add quotes '' to parameters value,
                              False - otherwise

        Note: replaces param()
        """
        if not self._paramExists(param):
            return None

        param = param.lower()
        if quotes:
            return self._params[param]

        return self._unquote(self._params[param])

    def set(self, param, val, quotes=False):
        """
        Sets existing parameter to the specified value.
        If no parameter exists, create one
        
            param: (str) -- Parameter name
            val: (str) -- Parameter value
            quotes: (bool) -- Add quotes to the value or not
        """
        param = param.lower()
        if quotes:
            val = self._quote(val)

        self._params[param] = val

    # TODO: Rename to params() in the future
    def paramlist(self):
        """
        Returns list of parameter names
        """
        return self._params.keys()

    def remove(self, param):
        """
        Deletes parameter

            param: (str) -- Name of the parameter
        """
        if self._paramExists(param):
            del (self._params[param])

    def exists(self, param):
        """
        Checks if parameter exists in the namelist

            param: (str) -- Name of the parameter
        """
        return self._paramExists(param)

    def _quote(self, val):
        """
        Quotes value with "'" quote mark

            val: (str) -- Value to be quoted
        """
        return "'" + val.strip('"').strip("'") + "'"

    def _unquote(self, val):
        """
        Removes quotes "'" (unquotes) on both sides of the string

            val: (str) -- Value to be unquoted
        """
        return val.strip('"').strip("'")

    def toString(self, indent=4, br="\n"):
        """
        Dumps namelist as a sting
        
            indent: (int) -- Number of spaces in indent for parameters
            br: (str) -- Separator between parameters
        """
        ind = ""
        for i in range(indent):  # Populate indent
            ind += " "

        s = '&%s%s' % (self.name().upper(), br)

        for p in self._params.keys():
            s += '%s%s = %s,%s' % (ind, p, self._params[p], br)

        s += "/%s" % br
        return s

    def _paramExists(self, param):
        """
        Checks if parameter exists in self._params

            param: (str) -- Name of the parameter
        """
        try:
            param = param.lower()
            self._params[param]
            return True
        except KeyError:  # parameter is not present
            return False

    # DEPRICATED METHODS:
    # DEPRICATED: Use get() instead
    def param(self, param, quotes=True):
        return self.get(param, quotes)

    # DEPRICATED: Use set() instead!
    def add(self, param, val, quotes=False):
        self.set(param, val, quotes)

    # DEPRICATED: Use set() instead!
    def editParam(self, param, val):
        self.set(param, val)

    # DEPRICATED: Use set() instead!
    def addParam(self, param, val):
        self.add(param, val)

    # DEPRICATED: Use remove() instead!
    def removeParam(self, param):
        self.remove(param)
Пример #34
0
class QEStructure():
    def __init__(self, qeConf):
        """the structure is initialized from PWSCF config file
           'lattice' and 'structure' are automatically updated"""
        self.filename = qeConf.filename
        self.atomicSpecies = OrderedDict()
        self.formatString = '%# .8f %# .8f %# .8f'
        # optConstraints three 1/0 for each coordinate of each atom
        self.optConstraints = []
        self.qeConf = qeConf
        self.lattice = QELattice()
        self.structure = Structure(lattice=self.lattice.diffpy())
        self.nat = None
        self.ntyp = None

    def parseInput(self):
        self.setStructureFromQEInput()

    def parseOutput(self, pwscfOutputFile):
        self.setStructureFromPWOutput(pwscfOutputFile)

    def setStructureFromPWOutput(self, pwscfOutputFile):
        """
        Loads structure from PWSCF output file. If there was geometry
        optimization (relax or vc-relax), the structure will be reinitialized
        from the last step of the optimization
        """
        file = open(pwscfOutputFile)
        pwscfOut = file.readlines()
        pseudoList = []
        atomList = []
        massList = []
        self.atomicSpecies = OrderedDict()
        self.atomicPositionsType = 'alat'
        # parse beginning:
        for i, line in enumerate(pwscfOut):
            if 'lattice parameter (a_0)' in line:
                a_0 = float(line.split()[4])
            if 'bravais-lattice index' in line:
                ibrav = int(line.split('=')[1])
            if 'number of atoms/cell' in line:
                self.nat = int(line.split('=')[1])
            if 'number of atomic types' in line:
                self.ntyp = int(line.split('=')[1])
            if 'PseudoPot.' in line:
                pseudoList.append(line.split('read from file')[1].strip())
            if 'atomic species   valence    mass     pseudopotential' in line:
                for j in range(self.ntyp):
                    atomList.append(pwscfOut[i + j + 1].split()[0])
                    massList.append(float(pwscfOut[i + j + 1].split()[2]))
            if 'crystal axes: (cart. coord. in units of a_0)' in line:
                latticeVectors = [
                    [float(f) * a_0 for f in pwscfOut[i + 1].split()[3:6]],
                    [float(f) * a_0 for f in pwscfOut[i + 2].split()[3:6]],
                    [float(f) * a_0 for f in pwscfOut[i + 3].split()[3:6]]
                ]
                self.lattice.setLatticeFromQEVectors(ibrav, latticeVectors)
            if 'site n.     atom                  positions (a_0 units)' in line:
                self.structure = Structure(lattice=self.lattice.diffpy())
                for n in range(self.nat):
                    words = pwscfOut[i + n + 1].split()
                    atomSymbol = words[1]
                    coords = [float(w) for w in words[6:9]]
                    constraint = []
                    self.optConstraints.append(
                        numpy.array(constraint, dtype=int))
                    #print numpy.array(coords[0:3])*a_0
                    coords = self.lattice.diffpy().fractional(
                        numpy.array(coords[0:3]) * a_0)
                    self.structure.addNewAtom(atomSymbol,
                                              xyz=numpy.array(coords[0:3]))

        for a, m, p in zip(atomList, massList, pseudoList):
            self.atomicSpecies[a] = AtomicSpecies(a, m, p)

        #print 'Input structure from output file: ', self.toString()
        #Parse end:
        # Find all geometry optimization steps
        posList = [
            i for i, line in enumerate(pwscfOut) if '!    total energy' in line
        ]
        lastSection = pwscfOut[posList[-1]:]
        for i, line in enumerate(lastSection):
            if 'CELL_PARAMETERS (alat)' in line:
                latticeVectors = [
                    [float(f) * a_0 for f in lastSection[i + 1].split()],
                    [float(f) * a_0 for f in lastSection[i + 2].split()],
                    [float(f) * a_0 for f in lastSection[i + 3].split()]
                ]
                self.lattice.setLatticeFromQEVectors(ibrav, latticeVectors)
                #self.lattice = QELattice(ibrav = ibrav, base = latticeVectors)
                print self.lattice.diffpy().base
            if 'ATOMIC_POSITIONS (alat)' in line:
                self.structure = Structure(lattice=self.lattice.diffpy())
                for n in range(self.nat):
                    words = lastSection[i + n + 1].split()
                    atomSymbol = words[0]
                    coords = [float(w) for w in words[1:4]]
                    constraint = []
                    if len(words) > 4:
                        constraint = [int(c) for c in words[4:7]]
                    self.optConstraints.append(
                        numpy.array(constraint, dtype=int))
                    coords = self.lattice.diffpy().fractional(
                        numpy.array(coords[0:3]) * a_0)
                    self.structure.addNewAtom(atomSymbol,
                                              xyz=numpy.array(coords[0:3]))

    def setStructureFromQEInput(self):
        """ Loads structure from PWSCF config file"""
        self.atomicSpecies = OrderedDict()
        self.lattice.setLatticeFromPWInput(self.qeConf)
        #self.lattice = QELattice(qeConf = self.qeConf)
        self.structure = Structure(lattice=self.lattice.diffpy())
        self.nat = int(self.qeConf.namelist('system').param('nat'))
        self.ntyp = int(self.qeConf.namelist('system').param('ntyp'))
        atomicLines = self.qeConf.card('atomic_positions').lines()
        self.atomicPositionsType = self.qeConf.card('atomic_positions').arg()
        if self.atomicPositionsType == 'bohr' or self.atomicPositionsType == 'angstrom':
            raise NotImplementedError
        if self.atomicPositionsType == None:
            self.atomicPositionsType = 'alat'
        for line in atomicLines:
            if '!' not in line:
                words = line.split()
                coords = [float(w) for w in words[1:4]]
                constraint = []
                if len(words) > 4:
                    constraint = [int(c) for c in words[4:7]]
                self.optConstraints.append(numpy.array(constraint, dtype=int))
                atomSymbol = words[0]
                if self.atomicPositionsType == 'alat':
                    coords = self.lattice.diffpy().fractional(
                        numpy.array(coords[0:3]) * self.lattice.a0)
                if self.atomicPositionsType == 'crystal':
                    coords = numpy.array(coords[0:3])
                self.structure.addNewAtom(atomSymbol,
                                          xyz=numpy.array(coords[0:3]))
                # parse mass ATOMIC_SPECIES section:
                atomicSpeciesLines = self.qeConf.card('atomic_species').lines()
                for line in atomicSpeciesLines:
                    if '!' not in line:
                        atomicSpeciesWords = line.split()
                        element = atomicSpeciesWords[0]
                        mass = float(atomicSpeciesWords[1])
                        ps = atomicSpeciesWords[2]
                        self.atomicSpecies[element] = AtomicSpecies(
                            element, mass, ps)

    def toString(self):
        s = self.lattice.toString() + '\n'
        if self.atomicPositionsType == 'alat':
            s = s + 'Atomic positions in units of lattice parametr "a":\n'
        if self.atomicPositionsType == 'crystal':
            s = s + 'Atomic positions in crystal coordinates:\n'
        for atom, constraint in zip(self.structure, self.optConstraints):
            if self.atomicPositionsType == 'alat':
                coords = self.lattice.diffpy().cartesian(
                    atom.xyz) / self.lattice.a
                coords = self.formatString % (coords[0], coords[1], coords[2])
            else:
                if self.atomicPositionsType == 'crystal':
                    coords = self.formatString % (v[0], v[1], v[2]) % (
                        atom.xyz[0], atom.xyz[1], atom.xyz[2])
                else:
                    raise NonImplementedError
            s = s + '%-3s'%atom.element + '    ' + coords + '  ' \
                    + str(constraint)[1:-1] + '\n'

        s = s + '\n'
        for element, specie in self.atomicSpecies.items():
            s = s + specie.toString() + '\n'

        return s

    def updatePWInput(self, qeConf=None):

        if qeConf == None:
            qeConf = self.qeConf

        self.lattice.updatePWInput(qeConf)

        qeConf.namelist('system').remove('ntyp')
        qeConf.namelist('system').remove('nat')
        qeConf.namelist('system').add('ntyp', self.ntyp)
        qeConf.namelist('system').add('nat', self.nat)

        if 'atomic_positions' in qeConf.cards:
            qeConf.removeCard('atomic_positions')
        qeConf.createCard('atomic_positions')
        qeConf.card('atomic_positions').setArg(self.atomicPositionsType)
        for atom, constraint in zip(self.structure, self.optConstraints):
            if self.atomicPositionsType == 'alat':
                coords = self.lattice.diffpy().cartesian(
                    atom.xyz) / self.lattice.a
                coords = self.formatString % (coords[0], coords[1], coords[2])
            else:
                if self.atomicPositionsType == 'crystal':
                    coords = self.formatString % (atom.xyz[0], atom.xyz[1],
                                                  atom.xyz[2])
                else:
                    raise NonImplementedError
            line = '%-3s' % atom.element + '    ' + coords + '  ' + str(
                constraint)[1:-1]
            qeConf.card('atomic_positions').addLine(line)

        # update ATOMIC_SPECIES card
        if 'atomic_species' in qeConf.cards:
            qeConf.removeCard('atomic_species')
        qeConf.createCard('atomic_species')
        for element, specie in self.atomicSpecies.items():
            qeConf.card('atomic_species').addLine(specie.toString())

    def save(self, fname=None):
        """Writes/updates structure into PW config file,
           if the file does not exist, new one will be created"""
        if fname != None:
            filename = fname
            self.lattice.save(filename)
            qeConf = QEInput(fname)
            qeConf.parse()
        else:
            filename = self.filename
            self.lattice.save(filename)
            qeConf = self.qeConf
        self.updatePWInput(qeConf)

        qeConf.save(filename)

    def diffpy(self):
        return self.structure
Пример #35
0
class QEStructure():
    
    def __init__(self, qeConf):
        """the structure is initialized from PWSCF config file
           'lattice' and 'structure' are automatically updated"""
        self.filename = qeConf.filename
        self.atomicSpecies = OrderedDict()
        self.formatString = '%# .8f %# .8f %# .8f'
        # optConstraints three 1/0 for each coordinate of each atom
        self.optConstraints = []
        self.qeConf = qeConf
        #self.qeConf.parse()
        #self.setStructureFromQEInput()
        self.lattice = None
        self.structure = None
        self.nat = None
        self.ntyp = None
        
        
    def parseInput(self):
        self.setStructureFromQEInput()
        
    def parseOutput(self, pwscfOutputFile):
        self.setStructureFromPWOutput(pwscfOutputFile)

#    def _parseAtomicPositions(self, pwscfOut):
#        for n in range(self.nat):
#            words = pwscfOut[i + n + 1].split()
#            atomSymbol = words[0]
#            coords = [float(w) for w in words[1:4]]
#            constraint = []
#            if len(words) > 4:
#                constraint = [int(c) for c in words[4:7]]
#            self.optConstraints.append(numpy.array(constraint, dtype = int))
#            print numpy.array(coords[0:3])*a_0
#            coords = self.lattice.matter().fractional(numpy.array(coords[0:3])*a_0)
#            self.structure.addNewAtom(atomSymbol, xyz = numpy.array(coords[0:3]))

    def setStructureFromPWOutput(self, pwscfOutputFile): 
        """
        Loads structure from PWSCF output file. If there was geometry
        optimization (relax or vc-relax), the structure will be reinitialized
        from the last step of the optimization
        """
        file = open(pwscfOutputFile)
        pwscfOut = file.readlines()
        pseudoList = []
        atomList = []
        massList = []
        self.atomicSpecies = OrderedDict()
        self.atomicPositionsType = 'alat'  
        # parse beginning:
        for i, line in enumerate(pwscfOut):
            if 'lattice parameter (a_0)' in line:
                a_0 = float(line.split()[4])
            if 'bravais-lattice index' in line:
                ibrav = int(line.split('=')[1])
            if 'number of atoms/cell' in line:
                self.nat = int(line.split('=')[1])
            if 'number of atomic types' in line:
                self.ntyp = int(line.split('=')[1])
            if 'PseudoPot.' in line:
                pseudoList.append(line.split('read from file')[1].strip())
            if 'atomic species   valence    mass     pseudopotential' in line:
                for j in range(self.ntyp):
                    atomList.append(pwscfOut[i+j+1].split()[0])
                    massList.append(float(pwscfOut[i+j+1].split()[2]))
            if 'crystal axes: (cart. coord. in units of a_0)' in line:
                latticeVectors = [[float(f)*a_0 for f in pwscfOut[i + 1].split()[3:6] ],
                                  [float(f)*a_0 for f in pwscfOut[i + 2].split()[3:6] ],
                                  [float(f)*a_0 for f in pwscfOut[i + 3].split()[3:6] ]]
                self.lattice = QELattice(ibrav = ibrav, base = latticeVectors)
            if 'site n.     atom                  positions (a_0 units)' in line:
                self.structure = Structure(lattice = self.lattice.matter())
                for n in range(self.nat):
                    words = pwscfOut[i + n + 1].split()
                    atomSymbol = words[1]
                    coords = [float(w) for w in words[6:9]]
                    constraint = []
                    self.optConstraints.append(numpy.array(constraint, dtype = int))
                    #print numpy.array(coords[0:3])*a_0
                    coords = self.lattice.matter().fractional(numpy.array(coords[0:3])*a_0)
                    self.structure.addNewAtom(atomSymbol, xyz = numpy.array(coords[0:3]))

        for a, m, p in zip(atomList, massList, pseudoList):
            self.atomicSpecies[a] = AtomicSpecies(a, m, p)

        #print 'Input structure from output file: ', self.toString()
        #Parse end:
        # Find all geometry optimization steps
        posList =  [i for i,line in enumerate(pwscfOut) if '!    total energy' in line]
        lastSection = pwscfOut[posList[-1]:]
        for i, line in enumerate(lastSection):
            if 'CELL_PARAMETERS (alat)' in line:
                latticeVectors = [[float(f)*a_0 for f in lastSection[i + 1].split() ],
                                  [float(f)*a_0 for f in lastSection[i + 2].split() ],
                                  [float(f)*a_0 for f in lastSection[i + 3].split() ]]
                self.lattice = QELattice(ibrav = ibrav, base = latticeVectors)
                print self.lattice.matter().base
            if 'ATOMIC_POSITIONS (alat)' in line:
                self.structure = Structure(lattice = self.lattice.matter())
                for n in range(self.nat):
                    words = lastSection[i + n + 1].split()
                    atomSymbol = words[0]
                    coords = [float(w) for w in words[1:4]]
                    constraint = []
                    if len(words) > 4:
                        constraint = [int(c) for c in words[4:7]]
                    self.optConstraints.append(numpy.array(constraint, dtype = int))
                    #print numpy.array(coords[0:3])*a_0
                    coords = self.lattice.matter().fractional(numpy.array(coords[0:3])*a_0)
                    self.structure.addNewAtom(atomSymbol, xyz = numpy.array(coords[0:3]))
                #self.lattice.ibrav = ibrav
        #print 'Output structure from output file: ', self.toString()
    
    
    def setStructureFromQEInput(self):
        """ Loads structure from PWSCF config file"""
        self.atomicSpecies = OrderedDict()
        self.lattice = QELattice(qeConf = self.qeConf)
        self.structure = Structure(lattice = self.lattice.matter())
        self.nat  = int(self.qeConf.namelist('system').param('nat'))
        self.ntyp  = int(self.qeConf.namelist('system').param('ntyp'))
        atomicLines = self.qeConf.card('atomic_positions').lines()
        self.atomicPositionsType = self.qeConf.card('atomic_positions').arg()
        if self.atomicPositionsType == 'bohr' or self.atomicPositionsType == 'angstrom':
            raise NotImplementedError
        if self.atomicPositionsType == None:
            self.atomicPositionsType = 'alat'
        for line in atomicLines:
            if '!' not in line:
                words = line.split()
                coords = [float(w) for w in words[1:4]]
                constraint = []
                if len(words) > 4:
                    constraint = [int(c) for c in words[4:7]]
                self.optConstraints.append(numpy.array(constraint, dtype = int))
                atomSymbol = words[0]
                if self.atomicPositionsType == 'alat':
                    coords = self.lattice.matter().fractional(numpy.array(coords[0:3])*self.lattice.a0)
                if self.atomicPositionsType == 'crystal':
                    coords = numpy.array(coords[0:3])
                self.structure.addNewAtom(atomSymbol, xyz = numpy.array(coords[0:3]))
                # parse mass ATOMIC_SPECIES section:
                atomicSpeciesLines = self.qeConf.card('atomic_species').lines()
                for line in atomicSpeciesLines:
                    if '!' not in line:
                        atomicSpeciesWords = line.split()
                        element = atomicSpeciesWords[0]
                        mass = float(atomicSpeciesWords[1])
                        ps = atomicSpeciesWords[2]
                        self.atomicSpecies[element] =  AtomicSpecies(element, mass, ps)


    def toString(self):
        s = self.lattice.toString() + '\n'
        if self.atomicPositionsType == 'alat':
            s = s + 'Atomic positions in units of lattice parametr "a":\n'        
        if self.atomicPositionsType == 'crystal':
            s = s + 'Atomic positions in crystal coordinates:\n'
        for atom, constraint in zip(self.structure, self.optConstraints):
            if self.atomicPositionsType == 'alat':      
                coords = self.lattice.matter().cartesian(atom.xyz)/self.lattice.a
                coords = self.formatString%(coords[0], coords[1], coords[2])
                #coords = str(coords/self.lattice.a)[1:-1]
            else:
                if self.atomicPositionsType == 'crystal':
                    #coords = str(atom.xyz)[1:-1]
                    coords = self.formatString%(v[0], v[1], v[2])%(atom.xyz[0], atom.xyz[1], atom.xyz[2])
                else:
                    raise NonImplementedError
            s = s + '%-3s'%atom.element + '    ' + coords + '  ' \
                    + str(constraint)[1:-1] + '\n'

        s = s + '\n'
        for element, specie in self.atomicSpecies.items():
            s = s + specie.toString() + '\n'

        return s


    def updatePWInput(self, qeConf = None):

        if qeConf == None:
            qeConf = self.qeConf

        self.lattice.updatePWInput(qeConf)

        qeConf.namelist('system').remove('ntyp')
        qeConf.namelist('system').remove('nat')
        qeConf.namelist('system').add('ntyp', self.ntyp)
        qeConf.namelist('system').add('nat', self.nat)

        if 'atomic_positions' in qeConf.cards:
            qeConf.removeCard('atomic_positions')
        qeConf.createCard('atomic_positions')
        qeConf.card('atomic_positions').setArg(self.atomicPositionsType)
        for atom, constraint in zip(self.structure, self.optConstraints):
            if self.atomicPositionsType == 'alat':
                coords = self.lattice.matter().cartesian(atom.xyz)/self.lattice.a
                coords = self.formatString%(coords[0], coords[1], coords[2])
            else:
                if self.atomicPositionsType == 'crystal':
                    #coords = str(atom.xyz)[1:-1]
                    coords = self.formatString%(atom.xyz[0], atom.xyz[1], atom.xyz[2])
                else:
                    raise NonImplementedError
            line = '%-3s'%atom.element + '    ' + coords + '  ' + str(constraint)[1:-1]
#            line = atom.element + ' ' + coords + ' ' + str(constraint)[1:-1]
            qeConf.card('atomic_positions').addLine(line)

        # update ATOMIC_SPECIES card
        if 'atomic_species' in qeConf.cards:
            qeConf.removeCard('atomic_species')
        qeConf.createCard('atomic_species')
        for element, specie in self.atomicSpecies.items():
            qeConf.card('atomic_species').addLine(specie.toString())


    def save(self, fname = None):
        """Writes/updates structure into PW config file,
           if the file does not exist, new one will be created"""
        if fname != None:
            filename = fname
            self.lattice.save(filename)
            qeConf = QEInput(fname)
            qeConf.parse()
        else:
            filename = self.filename
            self.lattice.save(filename)
            qeConf = self.qeConf
            #qeConf.parse()
        self.updatePWInput(qeConf )
            
        qeConf.save(filename)

    def diffpy(self):
        return self.structure
Пример #36
0
    def setStructureFromPWOutput(self, pwscfOutputFile):
        """
        Loads structure from PWSCF output file. If there was geometry
        optimization (relax or vc-relax), the structure will be reinitialized
        from the last step of the optimization
        """
        file = open(pwscfOutputFile)
        pwscfOut = file.readlines()
        pseudoList = []
        atomList = []
        massList = []
        self.atomicSpecies = OrderedDict()
        self.atomicPositionsType = 'alat'
        # parse beginning:
        for i, line in enumerate(pwscfOut):
            if 'lattice parameter (a_0)' in line:
                a_0 = float(line.split()[4])
            if 'bravais-lattice index' in line:
                ibrav = int(line.split('=')[1])
            if 'number of atoms/cell' in line:
                self.nat = int(line.split('=')[1])
            if 'number of atomic types' in line:
                self.ntyp = int(line.split('=')[1])
            if 'PseudoPot.' in line:
                pseudoList.append(line.split('read from file')[1].strip())
            if 'atomic species   valence    mass     pseudopotential' in line:
                for j in range(self.ntyp):
                    atomList.append(pwscfOut[i + j + 1].split()[0])
                    massList.append(float(pwscfOut[i + j + 1].split()[2]))
            if 'crystal axes: (cart. coord. in units of a_0)' in line:
                latticeVectors = [
                    [float(f) * a_0 for f in pwscfOut[i + 1].split()[3:6]],
                    [float(f) * a_0 for f in pwscfOut[i + 2].split()[3:6]],
                    [float(f) * a_0 for f in pwscfOut[i + 3].split()[3:6]]
                ]
                self.lattice.setLatticeFromQEVectors(ibrav, latticeVectors)
            if 'site n.     atom                  positions (a_0 units)' in line:
                self.structure = Structure(lattice=self.lattice.diffpy())
                for n in range(self.nat):
                    words = pwscfOut[i + n + 1].split()
                    atomSymbol = words[1]
                    coords = [float(w) for w in words[6:9]]
                    constraint = []
                    self.optConstraints.append(
                        numpy.array(constraint, dtype=int))
                    #print numpy.array(coords[0:3])*a_0
                    coords = self.lattice.diffpy().fractional(
                        numpy.array(coords[0:3]) * a_0)
                    self.structure.addNewAtom(atomSymbol,
                                              xyz=numpy.array(coords[0:3]))

        for a, m, p in zip(atomList, massList, pseudoList):
            self.atomicSpecies[a] = AtomicSpecies(a, m, p)

        #print 'Input structure from output file: ', self.toString()
        #Parse end:
        # Find all geometry optimization steps
        posList = [
            i for i, line in enumerate(pwscfOut) if '!    total energy' in line
        ]
        lastSection = pwscfOut[posList[-1]:]
        for i, line in enumerate(lastSection):
            if 'CELL_PARAMETERS (alat)' in line:
                latticeVectors = [
                    [float(f) * a_0 for f in lastSection[i + 1].split()],
                    [float(f) * a_0 for f in lastSection[i + 2].split()],
                    [float(f) * a_0 for f in lastSection[i + 3].split()]
                ]
                self.lattice.setLatticeFromQEVectors(ibrav, latticeVectors)
                #self.lattice = QELattice(ibrav = ibrav, base = latticeVectors)
                print self.lattice.diffpy().base
            if 'ATOMIC_POSITIONS (alat)' in line:
                self.structure = Structure(lattice=self.lattice.diffpy())
                for n in range(self.nat):
                    words = lastSection[i + n + 1].split()
                    atomSymbol = words[0]
                    coords = [float(w) for w in words[1:4]]
                    constraint = []
                    if len(words) > 4:
                        constraint = [int(c) for c in words[4:7]]
                    self.optConstraints.append(
                        numpy.array(constraint, dtype=int))
                    coords = self.lattice.diffpy().fractional(
                        numpy.array(coords[0:3]) * a_0)
                    self.structure.addNewAtom(atomSymbol,
                                              xyz=numpy.array(coords[0:3]))
Пример #37
0
    def setStructureFromPWOutput(self, pwscfOutputFile): 
        """
        Loads structure from PWSCF output file. If there was geometry
        optimization (relax or vc-relax), the structure will be reinitialized
        from the last step of the optimization
        """
        file = open(pwscfOutputFile)
        pwscfOut = file.readlines()
        pseudoList = []
        atomList = []
        massList = []
        self.atomicSpecies = OrderedDict()
        self.atomicPositionsType = 'alat'  
        # parse beginning:
        for i, line in enumerate(pwscfOut):
            if 'lattice parameter (a_0)' in line:
                a_0 = float(line.split()[4])
            if 'bravais-lattice index' in line:
                ibrav = int(line.split('=')[1])
            if 'number of atoms/cell' in line:
                self.nat = int(line.split('=')[1])
            if 'number of atomic types' in line:
                self.ntyp = int(line.split('=')[1])
            if 'PseudoPot.' in line:
                pseudoList.append(line.split('read from file')[1].strip())
            if 'atomic species   valence    mass     pseudopotential' in line:
                for j in range(self.ntyp):
                    atomList.append(pwscfOut[i+j+1].split()[0])
                    massList.append(float(pwscfOut[i+j+1].split()[2]))
            if 'crystal axes: (cart. coord. in units of a_0)' in line:
                latticeVectors = [[float(f)*a_0 for f in pwscfOut[i + 1].split()[3:6] ],
                                  [float(f)*a_0 for f in pwscfOut[i + 2].split()[3:6] ],
                                  [float(f)*a_0 for f in pwscfOut[i + 3].split()[3:6] ]]
                self.lattice = QELattice(ibrav = ibrav, base = latticeVectors)
            if 'site n.     atom                  positions (a_0 units)' in line:
                self.structure = Structure(lattice = self.lattice.matter())
                for n in range(self.nat):
                    words = pwscfOut[i + n + 1].split()
                    atomSymbol = words[1]
                    coords = [float(w) for w in words[6:9]]
                    constraint = []
                    self.optConstraints.append(numpy.array(constraint, dtype = int))
                    #print numpy.array(coords[0:3])*a_0
                    coords = self.lattice.matter().fractional(numpy.array(coords[0:3])*a_0)
                    self.structure.addNewAtom(atomSymbol, xyz = numpy.array(coords[0:3]))

        for a, m, p in zip(atomList, massList, pseudoList):
            self.atomicSpecies[a] = AtomicSpecies(a, m, p)

        #print 'Input structure from output file: ', self.toString()
        #Parse end:
        # Find all geometry optimization steps
        posList =  [i for i,line in enumerate(pwscfOut) if '!    total energy' in line]
        lastSection = pwscfOut[posList[-1]:]
        for i, line in enumerate(lastSection):
            if 'CELL_PARAMETERS (alat)' in line:
                latticeVectors = [[float(f)*a_0 for f in lastSection[i + 1].split() ],
                                  [float(f)*a_0 for f in lastSection[i + 2].split() ],
                                  [float(f)*a_0 for f in lastSection[i + 3].split() ]]
                self.lattice = QELattice(ibrav = ibrav, base = latticeVectors)
                print self.lattice.matter().base
            if 'ATOMIC_POSITIONS (alat)' in line:
                self.structure = Structure(lattice = self.lattice.matter())
                for n in range(self.nat):
                    words = lastSection[i + n + 1].split()
                    atomSymbol = words[0]
                    coords = [float(w) for w in words[1:4]]
                    constraint = []
                    if len(words) > 4:
                        constraint = [int(c) for c in words[4:7]]
                    self.optConstraints.append(numpy.array(constraint, dtype = int))
                    #print numpy.array(coords[0:3])*a_0
                    coords = self.lattice.matter().fractional(numpy.array(coords[0:3])*a_0)
                    self.structure.addNewAtom(atomSymbol, xyz = numpy.array(coords[0:3]))
Пример #38
0
 def _get_atomicSpecies(self):
     atomicSpecies = OrderedDict()
     for a in self:
         atomicSpecies[a.symbol] = AtomicSpecies(symbol = a.symbol, \
                                     mass = a.mass, potential = a.potential)
     return atomicSpecies
Пример #39
0
 def __init__(self, name):
     self.__name = name.lower()  # keeps lower name
     self.params = OrderedDict()  # Replace dictionary by ordered dictionry
Пример #40
0
def callservice(conn, schemaname, servicename, querystring):
    try:
        t1 = datetime.datetime.now()
        # log the request
        logging.basicConfig(
            filename='../../htdocs/mstmp/REST_Services_Log.log',
            level=logging.INFO,
            format='%(asctime)s %(levelname)s %(message)s',
        )
        #         logging.info("REST REQUEST: " + web.ctx.home + web.ctx.path + web.ctx.query)
        # PARSE THE STANDARD OPTIONAL INPUT PARAMETERS
        # get the input parameters
        params = getQueryStringParams(
            querystring
        )  # the unquoting is to handle encoded parameters (like from extJS - 1,2,3 as a parameter becomes 1%2C2%2C3
        # get the standard optional parameters from the url
        format = params.setdefault('format', 'json')
        fields = params.setdefault('fields', '').split(
            ","
        )  # fields will be passed as an array, e.g. iucn_species_id,wdpa_id
        includemetadata = params.setdefault('includemetadata', 'true')
        metadataName = params.setdefault('metadataname', 'metadata')
        rootName = params.setdefault('rootname', 'records')
        parseparams = params.setdefault('parseparams', 'true')
        sortField = params.setdefault('sortfield', '')
        decimalPlaceLimit = params.setdefault('dplimit', '2')
        isHadoop = (
            'true' if (servicename[-2:] == '_h') else 'false'
        )  # if the service is a call to a hadoop method then set a flag

        # remove the standard optional parameters from the dictionary so we are left with just the parameters required for the function
        del (params['format'], params['fields'], params['includemetadata'],
             params['parseparams'], params['metadataname'], params['rootname'],
             params['sortfield'], params['dplimit'])
        if 'callback' in params.keys():
            del (params['callback'])
        # check if the service name is valid
        if not (isValidServiceName(servicename)):
            raise RESTServicesError('Invalid servicename')

        # authorise with ecas if needed


#         if requiresAuthentication(servicename):
#             if isAuthenticated() == False:
#                 web.ctx.status = '401 Unauthorized'
#                 web.header("Content-Type", "text/html")
#                 return "<html><head></html><body><h1>Authentication required</h1></body></html>"

# if it is a Hadoop query then we need to run if first before we actually use the values to get the data from postgresql
        if (isHadoop.lower() == 'true'):
            hadoopData = runHadoopQuery(conn, servicename, params)
            if hadoopData == '[]': hadoopData = '[-1]'
            servicename = "_" + servicename  # now call the postgresql function
            params.clear()
            params['species_ids'] = str(hadoopData)[1:-1]

        # PARSE AND CONVERT THE DATA TYPES OF THE OTHER INPUT PARAMETERS
        # get all the parameters for the function from postgresql
        conn.cur.callproc('utils.dopa_rest_getparams', [servicename])
        # get the function parameters as a string and split this into a list, e.g. wdpa_id integer, presence_id integer[] -->  ['wdpa_id integer', ' presence_id integer[]']
        functionparams = conn.cur.fetchone()
        hasparams = True if functionparams[0] else False
        if hasparams:
            functionparams = functionparams[0].split(',')
            # get the names of the function parameters which are array types
            arrayparamnames = [
                p.strip().split(" ")[0] for p in functionparams if '[' in p
            ]
            # convert the array values into lists
            for key in params.keys():
                if key in arrayparamnames:
                    strlist = params[key].split(",")
                    isnum = isNumeric(strlist[0])
                    if isnum:
                        params[key] = [int(s) for s in strlist]
                    else:
                        params[key] = strlist
            # get the full list of function parameter names
            functionparamnames = [
                p.strip().split(" ")[0] for p in functionparams
            ]
            # check that all parameters are correct
            invalidparamnames = [
                n for n in params.keys() if n not in functionparamnames
            ]
            if invalidparamnames and parseparams == 'true':
                raise RESTServicesError('Invalid parameters: ' +
                                        ",".join(invalidparamnames))
            # put the input parameters in the right order
            params = OrderedDict([(n, params[n]) for n in functionparamnames
                                  if n in params.keys()])

        # GET THE SORT CLAUSE
        if sortField != "":
            sortClause = ' ORDER BY "' + sortField + '"'
        else:
            sortClause = ""

        # GET THE FIELDS CLAUSE
        if fields != ['']:
            fieldsClause = ",".join(fields)
        else:
            fieldsClause = "*"

        # RUN THE QUERY
        if hasparams:
            sql = "SELECT " + fieldsClause + " from " + schemaname + "." + servicename + "(" + ",".join(
                [n + ":=%(" + n + ")s" for n in params]
            ) + ")" + sortClause + ";"  # run the query using named parameters
            conn.cur.execute(sql, params)
        else:
            sql = "SELECT * from " + schemaname + "." + servicename + "()" + sortClause + ";"
            conn.cur.execute(sql)
        rows = conn.cur.fetchall()

        # PROCESS THE ROWS AND WRITE THEM BACK TO THE CLIENT
        conn.cur.close()
        t2 = datetime.datetime.now()

        # METADATA SECTION OF RESPONSE
        allfields = [d.name for d in conn.cur.description]
        if (fields == ['']): fields = allfields
        fieldcount = len(fields)
        fieldsdict = [
            dict([("name", d.name),
                  ("type", gettypefromtypecode(d.type_code))])
            for d in conn.cur.description if (d.name in fields)
        ]
        if len(fieldsdict) != len(fields):
            raise RESTServicesError('Invalid output fields')
        metadatadict = OrderedDict([
            ("duration", str(t2 - t1)), ("error", None),
            ("idProperty", conn.cur.description[0].name),
            ("successProperty", 'success'), ("totalProperty", 'recordCount'),
            ("success", True), ("recordCount", int(conn.cur.rowcount)),
            ("root", rootName), ("fields", fieldsdict)
        ])

        # RECORDS SECTION OF THE RESPONSE
        # parse the float values and set the correct number of decimal places according to the decimalPlaceLimit variable - dont include lat/long fields as these must have more decimal places
        floatColumns = [
            i for i, d in enumerate(fieldsdict)
            if d['type'] == 'float' and d['name'] not in ['lat', 'lng']
        ]
        if len(floatColumns) > 0:
            for floatColumn in floatColumns:
                for row in rows:
                    if type(row[floatColumn]
                            ) != NoneType:  # check that the data is not null
                        row[floatColumn] = round(row[floatColumn],
                                                 int(decimalPlaceLimit))

        # return the data
        colsRequired = [allfields.index(field) for field in fields]
        if format in ['json', 'array']:
            if format == 'json':
                recordsdict = [
                    OrderedDict([(allfields[col], row[col])
                                 for col in range(fieldcount)
                                 if (col in colsRequired)]) for row in rows
                ]
            else:
                recordsdict = [[
                    row[col] for col in range(fieldcount)
                    if (col in colsRequired)
                ] for row in rows]
            json.encoder.FLOAT_REPR = lambda f: (
                "%.14g" % f
            )  # this specifies how many decimal places are returned in the json with float values - currently set to 14 - good enough for returning lat/long coordinates
            if (includemetadata.lower() == 'true'):
                responsejson = json.dumps(dict([(metadataName, metadatadict),
                                                (rootName, recordsdict)]),
                                          indent=1,
                                          cls=CustomJSONEncoder)
            else:
                responsejson = json.dumps(dict([(rootName, recordsdict)]),
                                          indent=1,
                                          cls=CustomJSONEncoder)
            return getJsonResponse(responsejson)

        elif format in ['xml', 'xmlverbose']:
            root = etree.Element('results')
            recordsnode = etree.Element(rootName)
            recordsdicts = [
                OrderedDict([
                    (allfields[col], str(row[col]).decode('utf-8'))
                    for col in range(fieldcount)
                    if (col in colsRequired) and str(row[col]) != 'None'
                ]) for row in rows
            ]  #
            if format == 'xml':
                recordselements = [
                    etree.Element('record', element)
                    for element in recordsdicts
                ]
                for recordelement in recordselements:
                    recordsnode.append(recordelement)
            else:
                for recordelement in recordsdicts:
                    record = etree.Element('record')
                    for (n, v) in recordelement.items():
                        el = etree.Element(n)
                        el.text = v
                        record.append(el)
                    recordsnode.append(record)
            root.append(recordsnode)
            web.header("Content-Type", "text/xml")
            #             web.header("Content-Type", "application/Excel") # doesnt work!
            #             web.header("Content-Disposition", "attachment; filename=test.xml")
            return etree.tostring(root)

        elif format == 'sms':
            _twilio = twilio()
            client = TwilioRestClient(
                _twilio.twilio_account_sid,
                _twilio.twilio_auth_token)  # use the twilio api account
            bodystr = 'Hi Andrew - test species data: '
            bodystr = bodystr + str(rows[0])[:160 - len(bodystr)]
            message = client.sms.messages.create(to="+393668084920",
                                                 from_="+19712647662",
                                                 body=bodystr)  # my mobile
            return message

        elif format == 'email':
            _amazon_ses = amazon_ses()
            amazonSes = AmazonSES(
                _amazon_ses.AccessKeyID, _amazon_ses.SecretAccessKey
            )  # use the amazon simple email service api account
            message = EmailMessage()
            message.subject = 'JRC REST Services Information Request'
            message.bodyHtml = getResultsAsHTML(rows, fieldcount, colsRequired,
                                                metadatadict)
            result = amazonSes.sendEmail('*****@*****.**',
                                         '*****@*****.**',
                                         message)  # to me
            return result

        elif format == 'html':
            htmlData = getResultsAsHTML(rows, fieldcount, colsRequired,
                                        metadatadict)
            web.header("Content-Type", "text/html")
            return "<html><head></head><body>" + htmlData + "</body></html>"

        elif format == 'csv':
            data = [[
                row[col] for col in range(fieldcount) if (col in colsRequired)
            ] for row in rows]
            colnames = ",".join([f["name"]
                                 for f in metadatadict["fields"]]) + "\n"
            output = colnames + "\n".join([
                p for p in [
                    ",".join(h) for h in [[getStringValue(col) for col in row]
                                          for row in data]
                ]
            ])
            filename = "dataDownload.csv"  #hardcoded for now
            f = open(r'../../htdocs/mstmp/' + filename, 'wb')
            f.write(output)
            f.close()
            web.header("Content-Type", "text/plain")
            web.header("Content-Disposition",
                       "attachment; filename=%s" % filename)
            return output

        elif format == 'pdf':
            config = pdfkit.configuration(
                wkhtmltopdf='/usr/local/bin/wkhtmltopdf')
            web.header("Content-Type", "application/pdf")
            htmlData = getResultsAsHTML(rows, fieldcount, colsRequired,
                                        metadatadict)
            return pdfkit.from_string(htmlData.decode('utf8'),
                                      False,
                                      configuration=config,
                                      options={
                                          'quiet': '',
                                          'encoding': "UTF-8"
                                      })

        else:
            raise RESTServicesError('Invalid response format: ' + format)

    except (RESTServicesError, DataError, ProgrammingError,
            exceptions.TypeError, IndexError, IntegrityError, AmazonError,
            OperationalError) as e:
        #        web.webapi.internalerror() #returns a internal server error 500
        t2 = datetime.datetime.now()
        msg = "There was an error sending the email. Make sure that the email address has been verified in Amazon Simple Email Services" if type(
            e) == AmazonError else e.message
        logging.error(msg + "\n")
        if type(e) == ProgrammingError:
            if ("column" in e.message) & ("does not exist"
                                          in e.message) & (sortField != ""):
                msg = "Invalid sortfield parameter: " + sortField
        return returnError(metadataName, rootName, t2 - t1, msg)
Пример #41
0
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)
Пример #42
0
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
Пример #43
0
class Namelist():
    """Namelist class that corresponds to Namelist in QE config file"""
    def __init__(self, name):
        self.__name = name.lower()  # keeps lower name
        self.params = OrderedDict()  # Replace dictionary by ordered dictionry

    def name(self):
        return self.__name

    def setName(self, name):
        self.__name = name.lower()

    def param(self, param, quotes=True):
        """Returns value of parameter 'param'"""
        if self.__paramExists(param):
            if quotes:
                return self.params[param]
            else:
                return self._unquote(self.params[param])
            return self.params[param]

        return None

    def add(self, param, val, quotes=False):
        "Adds parameter to the namelist"
        #param = param.lower()   # Should be lowered?
        if quotes:
            val = self._quote(val)

        self.params[param] = val

    def set(self, param, val, quotes=False):
        #  Replaces editParam() and addParam(). Merge with add()?
        "Sets existing parameter to the specified value. If it doesn't exist, it just ignores it " ""
        if self.__paramExists(param):
            if quotes:
                val = self._quote(val)

            self.params[param] = val

    def remove(self, param):
        """Deletes parameter"""
        if self.__paramExists(param):
            del (self.params[param])

    def exists(self, param):
        return self.__paramExists(param)

    def _quote(self, val):
        return "'" + val.strip('"').strip("'") + "'"

    def _unquote(self, val):
        return val.strip('"').strip("'")

    def toString(self, indent="    ", br="\n"):
        # Dump namelist
        # Should I use space?
        s = '&%s%s' % (self.name().upper(), br)

        for p in self.params.keys():
            s += '%s%s = %s,%s' % (indent, p, self.params[p], br)

        s += "/%s" % br
        return s

    def __paramExists(self, param):
        try:
            param = param.lower()
            self.params[param]
            return True
        except KeyError:  # parameter is not present
            return False

    # Depricated methods:
    # Depricated
    def addParam(self, param, val):
        self.add(param, val)

    # Depricated
    def editParam(self, param, val):
        self.set(param, val)

    # Depricated
    def removeParam(self, param):
        self.remove()
Пример #44
0
 def __init__(self, name):
     self.__name = name.lower() # keeps lower name
     self.params = OrderedDict() # Replace dictionary by ordered dictionry