opaldict.py 4.6 KB
Newer Older
1
from .PathNameGenerator import PathNameGenerator
adelmann's avatar
adelmann committed
2
from decimal import Decimal
3
from ast import literal_eval
4
import sys
gsell's avatar
gsell committed
5 6 7 8
"""
OpalDictionary class

@author: Andreas Adelmann <andreas.adelmann@psi.ch>
9
@author: Yves Ineichen
gsell's avatar
gsell committed
10 11
@version: 0.1
"""
12 13


gsell's avatar
gsell committed
14
class OpalDict:
15 16 17
    '''
    This file contains values from a .data file, plus some user provided values.
    '''
gsell's avatar
gsell committed
18 19

    def __init__(self, template):
20 21 22 23
        '''
        Parameters
        ==========
        template: str
24
            Path the .data file.
25
        '''
gsell's avatar
gsell committed
26 27 28 29
        self.dict = {}
        self.rangevars = {}
        self.uservars = []
        self.numRanges = 0
30 31

        self.path_name_generator = PathNameGenerator()
gsell's avatar
gsell committed
32 33 34 35 36 37 38
        self.fillDictionary(template)

    def __iter__(self):
        return self.dict.__iter__()

    def __setitem__(self, key, value):
        scalevars = {}
39
        scalevars['GUNSOLB'] = 1.0
gsell's avatar
gsell committed
40 41 42 43 44 45 46 47 48

        try:
            self.dict[key] = value * scalevars[key]
        except KeyError:
            self.dict[key] = value

    def __getitem__(self, key):
        return self.dict[key]

ext-neveu_n's avatar
ext-neveu_n committed
49 50
    def items(self):
        return self.dict.items()
51

gsell's avatar
gsell committed
52
    def fillDictionary(self, fileName):
53 54 55
        '''
        Read the given .data file and and the key-value pairs to self.
        '''
56
        fp = open(fileName, "r")
gsell's avatar
gsell committed
57
        for line in fp:
adelmann's avatar
adelmann committed
58 59
            if not line == "\n":
                li = line.strip()
60
                # ignore outcommented lines
adelmann's avatar
adelmann committed
61
                if not li.startswith("#"):
62
                    # cut off comments at the end of the line
adelmann's avatar
adelmann committed
63
                    aline = line.split("#")[0]
64
                    # the name-value pairs are separated by whitespace
65
                    name, val = aline.split()
adelmann's avatar
adelmann committed
66
                    self.dict[name.rstrip()] = val.lstrip().rstrip()
gsell's avatar
gsell committed
67 68
        fp.close()

69 70 71 72 73 74 75
    def dumpMapping(self):
        mapping = str(self.path_name_generator)
        if len(mapping) > 0:
            f = open('name_mapping', 'w')
            f.write(mapping)
            f.close()

gsell's avatar
gsell committed
76 77 78 79 80 81
    def generateDirectoryName(self):
        dirname = ""
        for p in self.uservars:
            dirname += "_" + str(p[0]) + "=" + str(p[1])
        for (k, v) in self.rangevars.items():
            dirname += "_" + str(k) + "=" + str(self.dict[k])
82
        return self.path_name_generator.compress(dirname)
gsell's avatar
gsell committed
83 84

    def scaleDictVar(self, var, scaleWith):
ext-neveu_n's avatar
ext-neveu_n committed
85 86
        if var in self.dict:
        #if self.dict.has_key(var):
gsell's avatar
gsell committed
87 88
            self.dict[var] = float(self.dict[var])*scaleWith

89
    def getType(self, s):
90 91 92 93
        try:
            return int(s)
        except ValueError:
            return float(s)
94

gsell's avatar
gsell committed
95 96 97 98 99 100 101
    def hasRanges(self):
        return self.numRanges > 0

    def Range(self):
        return self.rangevars

    def scale(self):
adelmann's avatar
adelmann committed
102
        self.scaleDictVar('GUNSOLB', 1.)
103

gsell's avatar
gsell committed
104
    def addUserValues(self, argv):
105 106 107 108 109 110 111 112
        '''
        Add user-provided key-value pairs to those from the .data fileself.

        Parameters
        ==========
        argv: str
            Command line arguments to runOPAL.py
        '''
gsell's avatar
gsell committed
113 114
        for arg in argv:
            if arg.find("=") > 0:
115 116 117

                data = str(arg.split(" "))        # arguments are separated by spaces
                eqsidx = data.find("=")           # idx of =
118 119
                var = data[2:eqsidx]
                rhs = data[eqsidx+1:len(data)-2]
adelmann's avatar
cleanup  
adelmann committed
120

ext-neveu_n's avatar
ext-neveu_n committed
121 122
                if var in self.dict:
                #if self.dict.has_key(var):
123
                    # check if we have a range
124 125
                    if rhs.find(':') > 0:
                        range = rhs.split(":")
gsell's avatar
gsell committed
126 127 128 129 130
                        if len(range) == 3:
                            rvar = []
                            for r in range:
                                rvar.append(self.getType(r))
                            self.rangevars[var] = rvar
131
                            self.numRanges = self.numRanges + 1
gsell's avatar
gsell committed
132
                        else:
133
                            print("OpalDict: Range has to be of the form from:to:step!")
134
                            sys.exit(1)
gsell's avatar
gsell committed
135
                    else:
136 137 138
                        try:
                            val = literal_eval(rhs)
                            if (isinstance(val, int) or isinstance(val, float)):
139
                                self.uservars.append((var, Decimal(rhs)))
140 141 142 143
                                self.dict[var] = Decimal(rhs) #self.getType(rhs)
                        except: # add string
                            self.uservars.append( (var, rhs) )
                            self.dict[var] = rhs
gsell's avatar
gsell committed
144
                else:
145
                    if var.find("--") < 0: # not a regular option
146
                        print(f'OpalDict: Key ({key}) not found cannot add to dictionary, check the OPAL template file')
147
                        sys.exit(1)