makeini.py 9.1 KB
Newer Older
carlos's avatar
carlos committed
1
# help: python3 makeini.py -h
2 3 4 5 6 7 8
import argparse
import errno
import glob
import logging
import os
import sys
import time
Mohcine Chraibi's avatar
Mohcine Chraibi committed
9
import itertools
10
import numpy as np
11
from numpy import linspace
12 13
from shutil import copy2, rmtree, move

Mohcine Chraibi's avatar
Mohcine Chraibi committed
14 15 16 17 18 19 20
try:
    import xml.etree.cElementTree as ET
except ImportError:
    import xml.etree.ElementTree as ET

SUCCESS = 0
FAILURE = 1
21

Mohcine Chraibi's avatar
Mohcine Chraibi committed
22 23
ego = os.path.basename(sys.argv[0]).split(".")[0] + ".txt"
print("ego: ", ego)
Mohcine Chraibi's avatar
Mohcine Chraibi committed
24 25 26 27
logfile = "log_%s"%ego
logging.basicConfig(filename=logfile, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# ============= some directories =============
#HOME = os.path.expanduser("~")
28
#TRUNK =  HOME + "/Workspace/ped|ynamics/JuPedSim/jpscore/"
Mohcine Chraibi's avatar
Mohcine Chraibi committed
29 30 31
#JPSCORE = TRUNK + "bin/jpscore"
#CURDIR = os.getcwd()
# ============= some default dictionaries =============
32 33 34 35 36 37 38 39 40 41 42 43
default_value = {'tmax':1000, 'seed':1111, 'geometry':'', 'number':1, 'num_threads':1,
                 'file':'', 'model_id':1, 'exit_crossing_strategy':3, 'cell_size':2.2,
                 'operational_model_id':1}

# only these tags can be multiplied
tags = ['tmax',
        'seed',
        'geometry',
        'exit_crossing_strategy',
        'num_threads',
        'stepsize']

44 45 46
# format tag-attribute
attributes_tags = ['group-pre_movement_mean',
                   'group-number',
Mohcine Chraibi's avatar
Mohcine Chraibi committed
47
                   'group-router_id',
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
                   'group-agent_parameter_id',
                   'group-premovement_sigma',
                   'agents-operational_model_id',
                   'linkedcells-cell_size',
                   'v0-mu', 'v0-sigma',
                   'v0_upstairs-mu', 'v0_upstairs-sigma',
                   'v0_downstairs-mu', 'v0_downstairs-sigma',
                   'bmax-mu', 'bmin-mu',
                   'amin-mu', 'tau-mu',
                   'atau-mu',
                   'force_ped-dist_max',
                   'force_ped-disteff_max',
                   'force_ped-interpolation_width',
                   'force_ped-nu',
                   'force_ped-b',
                   'force_ped-c',
                   'force_wall-dist_max',
                   'force_wall-disteff_max',
                   'force_wall-interpolation_width',
                   'force_wall-nu',
                   'force_wall-b',
Mohcine Chraibi's avatar
Mohcine Chraibi committed
69 70
                   'force_wall-c',
                   'source-frequency',
71
                   'source-agents_max',
Mohcine Chraibi's avatar
Mohcine Chraibi committed
72
               ]
73

74

75
# cor_tags = np.unique([att.split("_")[0] for att in attributes_tags]).astype(str)a
76 77
cor_tags = [att.split("-")[0] for att in attributes_tags]
attributes = [att.split(tag+"-")[1] for (att, tag) in zip(attributes_tags, cor_tags)]
78 79
cor_tags = np.unique(cor_tags)
attributes = np.unique(attributes)
Mohcine Chraibi's avatar
Mohcine Chraibi committed
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
input_tags = {}
# =======================================================
def getParserArgs():
    parser = argparse.ArgumentParser(description='Generate inifiles for jpscore simulations. ')
    parser.add_argument("-f", "--file", metavar='in-file', required=True, help='Master inifile')
    args = parser.parse_args()
    return args

# =======================================================
def make_dir(path):
    if os.path.exists(path):
        rmtree(path)
    try:
        os.makedirs(path)
    except OSError as exception:
        if exception.errno != errno.EEXIST:
            raise
# =======================================================
def get_tag(node):
    # geometry
    if node.tag == "geometry":
Mohcine Chraibi's avatar
Mohcine Chraibi committed
101 102 103
        geometries = []
        geom = glob.glob("%s/*.xml"%node.text)
        for g in geom:
104
            geometries.append('../geometries' + g.split(".xml")[0].split("geometries")[1] + ".xml")
Mohcine Chraibi's avatar
Mohcine Chraibi committed
105
        # the geometries are relative to the inifiles directory
Mohcine Chraibi's avatar
Mohcine Chraibi committed
106
        #print geometries
Mohcine Chraibi's avatar
Mohcine Chraibi committed
107
        return  geometries
Mohcine Chraibi's avatar
Mohcine Chraibi committed
108 109
    else:
        text = node.text
110

Mohcine Chraibi's avatar
Mohcine Chraibi committed
111 112 113 114 115 116 117
    if text:
        value = eval(text)
    else:
        value = default_value[node.tag]
    return value
# =======================================================
def get_attribute(node):
118 119
    text = ''
    values = []
Mohcine Chraibi's avatar
Mohcine Chraibi committed
120

carlos's avatar
carlos committed
121
    for node_attrib in list(node.attrib.keys()):
122 123 124 125 126 127
        if node_attrib in attributes:
            text = node.attrib[node_attrib]
            if text:
                value = eval(text)
            else:
                value = 0
128
            if isinstance(value, list) or isinstance(value, np.ndarray):
129
                if len(value) > 1:
130
                    values.append([value, str(node.tag)+"-"+str(node_attrib), node_attrib])
131 132

    return values
Mohcine Chraibi's avatar
Mohcine Chraibi committed
133 134 135 136 137 138 139
# =======================================================
def get_product(root):
    """
    read values, which may be lists or arrays of len>1 and  return a list of
    dics composed of the cartesian product of these lists.
    example:
    we read from the file (xml --> root) the following
Mohcine Chraibi's avatar
Mohcine Chraibi committed
140
    {'num_threads': [5, 1, 2], 'tmax': [1, 2]}
Mohcine Chraibi's avatar
Mohcine Chraibi committed
141 142 143 144 145 146 147 148
    return is:
    [
    {'numCPU': 5, 'tmax': 1}, {'numCPU': 5, 'tmax': 2},
    {'numCPU': 1, 'tmax': 1}, {'numCPU': 1, 'tmax': 2},
    {'numCPU': 2, 'tmax': 1}, {'numCPU': 2, 'tmax': 2}
    ]
    """
    for node in root.iter():
149
        tag = node.tag
Mohcine Chraibi's avatar
Mohcine Chraibi committed
150 151
        if tag in tags:   # ignore tags that are not of interest
            d = get_tag(node)
152
            if isinstance(d, list)  or isinstance(d, np.ndarray):
153
                # in case some tags have multiple values
carlos's avatar
carlos committed
154
                if tag not in input_tags and len(d) > 1:
155 156 157 158 159 160 161 162 163 164
            # ignore lists with one element (equiv to scalars)
            # if tag in tags:
                    input_tags[tag] = d
        elif bool(set(node.attrib.keys()) & set(attributes)): # check our list of attributes
            values = get_attribute(node) # d, atr_tag, attr
            # value, atr_tag, atr
            for value in values:
                d = value[0]
                atr_tag = value[1]
                input_tags[atr_tag] = d
Mohcine Chraibi's avatar
Mohcine Chraibi committed
165 166 167
        else:
            continue

Mohcine Chraibi's avatar
Mohcine Chraibi committed
168
    result_prod = [dict(zip(input_tags, x)) for x in itertools.product(*iter(input_tags.values()))]
169
    return result_prod
Mohcine Chraibi's avatar
Mohcine Chraibi committed
170 171 172
# =======================================================
def make_filename(directory, d):
    name = "%s/inifiles/ini"%directory
173
    traj = "../trajectories/traj" #%directory
carlos's avatar
carlos committed
174
    for key, value in d.items():
Mohcine Chraibi's avatar
Mohcine Chraibi committed
175 176
        if key == "geometry":
            value = os.path.basename(value)
Mohcine Chraibi's avatar
Mohcine Chraibi committed
177 178
        # if key == "num_threads":
            # value = "numCPU"
Mohcine Chraibi's avatar
Mohcine Chraibi committed
179 180
        name += "_" + key + "_" + str(value)
        traj += "_" + key + "_" + str(value)
Mohcine Chraibi's avatar
Mohcine Chraibi committed
181 182 183 184 185 186

    if not name.endswith("xml"):
        name += ".xml"
    if not traj.endswith("xml"):
        traj += ".xml"
    #print "name", (name)
Mohcine Chraibi's avatar
Mohcine Chraibi committed
187 188 189 190 191 192
    return name, traj
# =======================================================
def update_tag_value(root, tag, value):
    for rank in root.iter(tag):
        rank.text = str(value)
# =======================================================
193 194
def update_attrib_value(root, attr_tag, value):
    # location
195
    print ("update_attrib_value: ", attr_tag, value)
Mohcine Chraibi's avatar
Mohcine Chraibi committed
196
    # raw_input()
197
    if attr_tag == "location":  # e.g. location
Mohcine Chraibi's avatar
Mohcine Chraibi committed
198
        for r in root.iter():
carlos's avatar
carlos committed
199
            if attr_tag in r.attrib:
200
                r.attrib[attr_tag] = str(value)
Mohcine Chraibi's avatar
Mohcine Chraibi committed
201
        return
202

203 204
    attr = attr_tag.split("-")[1]
    cor_tag = attr_tag.split("-")[0]
205

Mohcine Chraibi's avatar
Mohcine Chraibi committed
206
    for r in root.iter(cor_tag):
carlos's avatar
carlos committed
207
        if attr in r.attrib:
Mohcine Chraibi's avatar
Mohcine Chraibi committed
208 209 210 211 212 213 214
            r.attrib[attr] = str(value)
# =======================================================
def make_file(masterfile, tree, result):
    """
    Given a list of dictionaries produce an xml file for each dic.
    The file is first copied from masterfile.
    """
Mohcine Chraibi's avatar
Mohcine Chraibi committed
215
    directory = os.path.dirname(os.path.abspath(masterfile))    #args.directory
Mohcine Chraibi's avatar
Mohcine Chraibi committed
216 217 218 219 220 221
    root = tree.getroot()
    for item in result:
        newfile, trajfile = make_filename(directory, item)
        copy2(masterfile, newfile)
        #update trajectory file
        update_attrib_value(root, "location", trajfile)
222
        if not os.path.isfile(newfile):
Mohcine Chraibi's avatar
Mohcine Chraibi committed
223 224
            logging.error("make_file: could not create file %s"%newfile)
            sys.exit(FAILURE)
carlos's avatar
carlos committed
225
        for tag, value in item.items():
Mohcine Chraibi's avatar
Mohcine Chraibi committed
226 227
            # print "tag: ", tag, "value:", value
            # raw_input()
228
            if tag in attributes_tags:
Mohcine Chraibi's avatar
Mohcine Chraibi committed
229 230 231 232 233 234 235 236 237
                update_attrib_value(root, tag, value)
            else:
                update_tag_value(root, tag, value)

        logging.info('>> %s'%newfile)
        tree.write(newfile)
# =======================================================

if __name__ == "__main__":
238
    time1 = time.clock()
Mohcine Chraibi's avatar
Mohcine Chraibi committed
239 240 241 242 243 244
    args = getParserArgs()

    masterfile = args.file
    if not os.path.isfile(masterfile):
        logging.error("ERROR: file %s does not exist."%masterfile)
        sys.exit(FAILURE)
245

Mohcine Chraibi's avatar
Mohcine Chraibi committed
246
    directory = os.path.dirname(os.path.abspath(masterfile))    #args.directory
Mohcine Chraibi's avatar
Mohcine Chraibi committed
247 248
    logging.info('working directory = <%s>'%directory)
    logging.info('master inifile = <%s>'%masterfile)
249 250 251
    make_dir("%s/trajectories"%directory)
    make_dir("%s/inifiles"%directory)

Mohcine Chraibi's avatar
Mohcine Chraibi committed
252 253 254 255
    tree = ET.parse(masterfile)
    root = tree.getroot()
    result = get_product(root)
    make_file(masterfile, tree, result)
256

Mohcine Chraibi's avatar
Mohcine Chraibi committed
257
    time2 = time.clock()
Mohcine Chraibi's avatar
Mohcine Chraibi committed
258 259 260 261
    print(directory)
    print("%s/%s"%(directory, logfile))
    print(os.path.isfile("%s/%s"%(directory, logfile)))

Mohcine Chraibi's avatar
Mohcine Chraibi committed
262 263 264 265 266 267 268
    if not  os.path.isfile("%s/%s"%(directory, logfile)):
        move(logfile, directory)
    logging.info('time elapsed: %.2f to generate %d files'%(time2 - time1, len(result)))
    if 0:
        sys.exit(FAILURE)
    else:
        sys.exit(SUCCESS)