Skip to content

process_config

Interfaces for Configuration values for programs - run_process.py - test_process.py

ProcessConfig

Configuration parameters for PROCESS runs

Source code in process/core/io/process_config.py
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
class ProcessConfig:
    """Configuration parameters for PROCESS runs"""

    filename = None
    """Configuration file name"""
    configfileexists = True
    wdir = "."
    """Working directory"""
    or_in_dat = "IN.DAT"
    """Original IN.DAT file"""
    niter = 10
    """(Maximum) number of iterations"""
    u_seed = None
    """User specified seed value for the random number generator"""
    factor = 1.5
    """Multiplication factor adjusting the range in which the original
iteration variables should get varied"""
    comment = " "
    """additional comment to be written into README.txt"""

    def echo(self):
        """echos the attributes of the class"""

        if self.wdir != ".":
            print(f"Working directory:   {self.wdir}")
        print(f"Original IN.DAT:     {self.or_in_dat}")
        print(f"Number of iterations {self.niter}")

        if self.u_seed is not None:
            print(f"random seed          {self.u_seed}")
        print(f"variable range factor {self.factor}")
        if self.filename is not None:
            print(f"Config file          {self.filename}")
        if self.comment != "":
            print(f"Comment  {self.comment}")

    def prepare_wdir(self):
        """prepares the working directory"""

        try:
            os.stat(self.wdir)
        except FileNotFoundError:
            os.mkdir(self.wdir)

        if self.or_in_dat != "IN.DAT" or self.wdir != ".":
            subprocess.call(["cp", self.or_in_dat, self.wdir + "/IN.DAT"])
        else:
            subprocess.call(["cp", self.or_in_dat, "Input_IN.DAT"])

        if self.configfileexists:
            subprocess.call(["cp", self.filename, self.wdir])
        os.chdir(self.wdir)
        subprocess.call(
            [
                "rm -f OUT.DAT MFILE.DAT README.txt SolverTest.out process.log *.pdf  uncertainties.nc time.info"
            ],
            shell=True,
        )

    def create_readme(self, directory="."):
        """creates README.txt containing comment"""

        if self.comment != "":
            Path(directory + "/README.txt").write_text(self.comment)

    def error_status2readme(self, directory="."):
        """appends PROCESS outcome to README.txt"""

        if os.path.isfile("MFILE.DAT"):
            m_file = MFile(filename=directory + "/MFILE.DAT")

            error_status = (
                f"Error status: {m_file.data['error_status'].get_scan(-1)}  "
                f"Error ID: {m_file.data['error_id'].get_scan(-1)}\n"
            )

            if self.comment != "":
                with open(directory + "/README.txt", "a") as readme:
                    readme.write(error_status)
            else:
                Path(directory + "/README.txt").write_text(error_status)

    def modify_in_dat(self):
        """modifies the original IN.DAT file"""

    def setup(self):
        """sets up the program for running"""

        self.echo()

        self.prepare_wdir()

        self.create_readme()

        self.modify_in_dat()

        check_in_dat()

        self.generator = default_rng(seed=self.u_seed)

    def get_comment(self):
        """gets the comment line from the configuration file"""

        if not self.configfileexists:
            return False

        try:
            with open(self.filename) as configfile:
                for line in configfile:
                    condense = line.replace(" ", "")
                    condense = condense.rstrip()
                    lcase = condense.lower()
                    if (
                        len(condense) > 0
                        and (condense[0] != "*")
                        and lcase[:7] == "comment"
                    ):
                        self.comment = line[line.find("=") + 1 :]
                        return True

                self.configfileexists = False
                return False
        except FileNotFoundError:
            print(f"Error: No config file named {self.filename}", file=stderr)

        return False

    def get_attribute(self, attributename):
        """gets class attribute from configuration file"""

        if not self.configfileexists:
            return None

        try:
            with open(self.filename) as configfile:
                for line in configfile:
                    condense = line.replace(" ", "")
                    if (condense[0] != "*") and len(condense) > 1 and "=" in line:
                        varname = line[: line.find("=")]
                        varname = varname.replace(" ", "")
                        varname = varname.upper()
                        auxvar = line[line.find("=") + 1 :]
                        auxvar = auxvar.replace(" ", "")
                        auxvar = auxvar.rstrip()
                        if varname == attributename.upper() and auxvar == "":
                            return None
                        if varname == attributename.upper() and auxvar != "":
                            return auxvar
        except FileNotFoundError:
            print(f"Error: No config file named {self.filename}", file=stderr)
            self.configfileexists = False
            return None

        return None

    def set_attributes(self):
        """sets the attributes of the class"""
        # TODO This Path/str filename type confusion is a mess and must be
        # sorted out once a run_process regression test is running. Using Paths
        # or strs to decide if we're running a test or not is a bad idea, but
        # works in the short term to get a test running.

        # If self.filename is an instance of Path, this is being run from the
        # test suite in a temp dir. Set the working dir and input filename
        # accordingly
        if isinstance(self.filename, Path):
            self.wdir = str(self.filename.parent)
            # TODO It appears that the input file for run_process shouldn't be
            # called IN.DAT. Calling it ref_IN.DAT for now
            original_in_dat = self.get_attribute("original_in_dat") or "ref_IN.DAT"
            self.or_in_dat = str(self.filename.parent / original_in_dat)
        else:
            # run_process is not being run by the test suite
            # Get working dir and input files from run_process.conf
            buf = self.get_attribute("wdir")
            if buf is not None:
                self.wdir = buf

            buf = self.get_attribute("ORIGINAL_IN_DAT")
            if buf is not None:
                self.or_in_dat = buf

        try:
            with open(self.or_in_dat) as indatfile:
                indatfile.close()
        except FileNotFoundError:
            print(
                f"Error: {self.or_in_dat} does not exist! Create file or modify config file!",
                file=stderr,
            )
            raise

        buf = self.get_attribute("niter")
        if buf is not None:
            self.niter = int(buf)

        buf = self.get_attribute("seed")
        if buf is not None:
            if buf == "None":
                self.u_seed = None
            else:
                self.u_seed = int(buf)

        buf = self.get_attribute("factor")
        if buf is not None:
            self.factor = float(buf)

        if not self.get_comment():
            print(f"No comment in config file {self.filename}")

    def run_process(self, input_path: Path, solver: str = "vmcon"):
        """Perform a single run of PROCESS, catching any errors.

        Parameters
        ----------
        input_path :
            the input file to run on
        solver :
            which solver to use, as specified in solver.py, defaults to "vmcon"
        """
        with open("process.log", "w") as logfile:
            print("PROCESS run started ...", end="")

            try:
                # Run process on an IN.DAT file
                subprocess.check_call(
                    ["process", "-i", str(input_path), "--solver", solver],
                    stdout=logfile,
                    stderr=logfile,
                )
            except subprocess.CalledProcessError as err:
                # Process has exited with a non-zero exit code. This is likely to
                # be due to hitting a "stop 1" in the Fortran. Catch this exception
                # to allow execution to continue without exiting
                print(
                    "Error: There was a problem with the PROCESS execution!",
                    err,
                    file=sys.stderr,
                )
                print("Refer to the logfile for more information!", file=sys.stderr)

        print("finished.")

filename = None class-attribute instance-attribute

Configuration file name

configfileexists = True class-attribute instance-attribute

wdir = '.' class-attribute instance-attribute

Working directory

or_in_dat = 'IN.DAT' class-attribute instance-attribute

Original IN.DAT file

niter = 10 class-attribute instance-attribute

(Maximum) number of iterations

u_seed = None class-attribute instance-attribute

User specified seed value for the random number generator

factor = 1.5 class-attribute instance-attribute

Multiplication factor adjusting the range in which the original iteration variables should get varied

comment = ' ' class-attribute instance-attribute

additional comment to be written into README.txt

echo()

echos the attributes of the class

Source code in process/core/io/process_config.py
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
def echo(self):
    """echos the attributes of the class"""

    if self.wdir != ".":
        print(f"Working directory:   {self.wdir}")
    print(f"Original IN.DAT:     {self.or_in_dat}")
    print(f"Number of iterations {self.niter}")

    if self.u_seed is not None:
        print(f"random seed          {self.u_seed}")
    print(f"variable range factor {self.factor}")
    if self.filename is not None:
        print(f"Config file          {self.filename}")
    if self.comment != "":
        print(f"Comment  {self.comment}")

prepare_wdir()

prepares the working directory

Source code in process/core/io/process_config.py
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
def prepare_wdir(self):
    """prepares the working directory"""

    try:
        os.stat(self.wdir)
    except FileNotFoundError:
        os.mkdir(self.wdir)

    if self.or_in_dat != "IN.DAT" or self.wdir != ".":
        subprocess.call(["cp", self.or_in_dat, self.wdir + "/IN.DAT"])
    else:
        subprocess.call(["cp", self.or_in_dat, "Input_IN.DAT"])

    if self.configfileexists:
        subprocess.call(["cp", self.filename, self.wdir])
    os.chdir(self.wdir)
    subprocess.call(
        [
            "rm -f OUT.DAT MFILE.DAT README.txt SolverTest.out process.log *.pdf  uncertainties.nc time.info"
        ],
        shell=True,
    )

create_readme(directory='.')

creates README.txt containing comment

Source code in process/core/io/process_config.py
87
88
89
90
91
def create_readme(self, directory="."):
    """creates README.txt containing comment"""

    if self.comment != "":
        Path(directory + "/README.txt").write_text(self.comment)

error_status2readme(directory='.')

appends PROCESS outcome to README.txt

Source code in process/core/io/process_config.py
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
def error_status2readme(self, directory="."):
    """appends PROCESS outcome to README.txt"""

    if os.path.isfile("MFILE.DAT"):
        m_file = MFile(filename=directory + "/MFILE.DAT")

        error_status = (
            f"Error status: {m_file.data['error_status'].get_scan(-1)}  "
            f"Error ID: {m_file.data['error_id'].get_scan(-1)}\n"
        )

        if self.comment != "":
            with open(directory + "/README.txt", "a") as readme:
                readme.write(error_status)
        else:
            Path(directory + "/README.txt").write_text(error_status)

modify_in_dat()

modifies the original IN.DAT file

Source code in process/core/io/process_config.py
110
111
def modify_in_dat(self):
    """modifies the original IN.DAT file"""

setup()

sets up the program for running

Source code in process/core/io/process_config.py
113
114
115
116
117
118
119
120
121
122
123
124
125
126
def setup(self):
    """sets up the program for running"""

    self.echo()

    self.prepare_wdir()

    self.create_readme()

    self.modify_in_dat()

    check_in_dat()

    self.generator = default_rng(seed=self.u_seed)

get_comment()

gets the comment line from the configuration file

Source code in process/core/io/process_config.py
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
def get_comment(self):
    """gets the comment line from the configuration file"""

    if not self.configfileexists:
        return False

    try:
        with open(self.filename) as configfile:
            for line in configfile:
                condense = line.replace(" ", "")
                condense = condense.rstrip()
                lcase = condense.lower()
                if (
                    len(condense) > 0
                    and (condense[0] != "*")
                    and lcase[:7] == "comment"
                ):
                    self.comment = line[line.find("=") + 1 :]
                    return True

            self.configfileexists = False
            return False
    except FileNotFoundError:
        print(f"Error: No config file named {self.filename}", file=stderr)

    return False

get_attribute(attributename)

gets class attribute from configuration file

Source code in process/core/io/process_config.py
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
def get_attribute(self, attributename):
    """gets class attribute from configuration file"""

    if not self.configfileexists:
        return None

    try:
        with open(self.filename) as configfile:
            for line in configfile:
                condense = line.replace(" ", "")
                if (condense[0] != "*") and len(condense) > 1 and "=" in line:
                    varname = line[: line.find("=")]
                    varname = varname.replace(" ", "")
                    varname = varname.upper()
                    auxvar = line[line.find("=") + 1 :]
                    auxvar = auxvar.replace(" ", "")
                    auxvar = auxvar.rstrip()
                    if varname == attributename.upper() and auxvar == "":
                        return None
                    if varname == attributename.upper() and auxvar != "":
                        return auxvar
    except FileNotFoundError:
        print(f"Error: No config file named {self.filename}", file=stderr)
        self.configfileexists = False
        return None

    return None

set_attributes()

sets the attributes of the class

Source code in process/core/io/process_config.py
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
def set_attributes(self):
    """sets the attributes of the class"""
    # TODO This Path/str filename type confusion is a mess and must be
    # sorted out once a run_process regression test is running. Using Paths
    # or strs to decide if we're running a test or not is a bad idea, but
    # works in the short term to get a test running.

    # If self.filename is an instance of Path, this is being run from the
    # test suite in a temp dir. Set the working dir and input filename
    # accordingly
    if isinstance(self.filename, Path):
        self.wdir = str(self.filename.parent)
        # TODO It appears that the input file for run_process shouldn't be
        # called IN.DAT. Calling it ref_IN.DAT for now
        original_in_dat = self.get_attribute("original_in_dat") or "ref_IN.DAT"
        self.or_in_dat = str(self.filename.parent / original_in_dat)
    else:
        # run_process is not being run by the test suite
        # Get working dir and input files from run_process.conf
        buf = self.get_attribute("wdir")
        if buf is not None:
            self.wdir = buf

        buf = self.get_attribute("ORIGINAL_IN_DAT")
        if buf is not None:
            self.or_in_dat = buf

    try:
        with open(self.or_in_dat) as indatfile:
            indatfile.close()
    except FileNotFoundError:
        print(
            f"Error: {self.or_in_dat} does not exist! Create file or modify config file!",
            file=stderr,
        )
        raise

    buf = self.get_attribute("niter")
    if buf is not None:
        self.niter = int(buf)

    buf = self.get_attribute("seed")
    if buf is not None:
        if buf == "None":
            self.u_seed = None
        else:
            self.u_seed = int(buf)

    buf = self.get_attribute("factor")
    if buf is not None:
        self.factor = float(buf)

    if not self.get_comment():
        print(f"No comment in config file {self.filename}")

run_process(input_path, solver='vmcon')

Perform a single run of PROCESS, catching any errors.

Parameters:

Name Type Description Default
input_path Path

the input file to run on

required
solver str

which solver to use, as specified in solver.py, defaults to "vmcon"

'vmcon'
Source code in process/core/io/process_config.py
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
def run_process(self, input_path: Path, solver: str = "vmcon"):
    """Perform a single run of PROCESS, catching any errors.

    Parameters
    ----------
    input_path :
        the input file to run on
    solver :
        which solver to use, as specified in solver.py, defaults to "vmcon"
    """
    with open("process.log", "w") as logfile:
        print("PROCESS run started ...", end="")

        try:
            # Run process on an IN.DAT file
            subprocess.check_call(
                ["process", "-i", str(input_path), "--solver", solver],
                stdout=logfile,
                stderr=logfile,
            )
        except subprocess.CalledProcessError as err:
            # Process has exited with a non-zero exit code. This is likely to
            # be due to hitting a "stop 1" in the Fortran. Catch this exception
            # to allow execution to continue without exiting
            print(
                "Error: There was a problem with the PROCESS execution!",
                err,
                file=sys.stderr,
            )
            print("Refer to the logfile for more information!", file=sys.stderr)

    print("finished.")

RunProcessConfig

Bases: ProcessConfig

Configuration parameters of the run_process.py program

Source code in process/core/io/process_config.py
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
class RunProcessConfig(ProcessConfig):
    """Configuration parameters of the run_process.py program"""

    no_allowed_unfeasible = 0
    """the number of allowed unfeasible points in a sweep"""
    create_itervar_diff = False
    """boolean to indicate the creation of a summary file of the iteration variable values at each stage"""
    add_ixc: ClassVar = []
    """ List of iteration variables to be added to IN.DAT"""
    del_ixc: ClassVar = []
    """List of iteration variables to be deleted from IN.DAT"""
    add_icc: ClassVar = []
    """List of constrained equations to be added to IN.DAT"""
    del_icc: ClassVar = []
    """List of constrained equations to be deleted from IN.DAT"""
    dictvar: ClassVar = {}
    """Dictionary mapping variable name to new value (replaces old or gets appended)"""
    del_var: ClassVar = []
    """List of variables to be deleted from IN.DAT"""

    def __init__(self, filename="run_process.conf"):
        """
        creates an instance of the RunProcessConfig class
        that stores all configuration parameters of the
        run_process.py
        """
        # TODO filename can be a Path object or a str here
        self.filename = filename

        super().set_attributes()

        buf = self.get_attribute("no_allowed_unfeasible")
        if buf is not None:
            self.no_allowed_unfeasible = int(buf)

        buf = self.get_attribute("create_itervar_diff")
        if buf is not None:
            if buf.lower() in ["true", "y", "yes"]:
                self.create_itervar_diff = True
            elif buf.lower() in ["false", "n", "no"]:
                self.create_itervar_diff = False
            else:
                print(
                    "WARNING: Value for create_itervar_diff is not defined!",
                    file=stderr,
                )

        self.add_ixc = self.get_attribute_csv_list("add_ixc")

        self.del_ixc = self.get_attribute_csv_list("del_ixc")

        self.add_icc = self.get_attribute_csv_list("add_icc")

        self.del_icc = self.get_attribute_csv_list("del_icc")

        self.set_del_var()

        self.set_dictvar()

    def get_attribute_csv_list(self, attributename):
        """get class attribute list from configuration file
        expects comma separated values
        """

        if not self.configfileexists:
            return []

        try:
            with open(self.filename) as configfile:
                attribute_list = []

                for line in configfile:
                    condense = line.replace(" ", "")
                    condense = condense.rstrip()
                    lcase = condense.lower()
                    if (
                        (len(condense) > 0)
                        and (condense[0] != "*")
                        and (attributename == lcase[: len(attributename)])
                    ):
                        buf = condense[condense.find("=") + 1 :].split(",")
                        if buf[-1] == "":  # if last value has ended on comma
                            buf = buf[:-1]
                        attribute_list += buf
        except FileNotFoundError:
            print(f"Error: No config file named {self.filename}", file=stderr)
            self.configfileexists = False
            return []
        return attribute_list

    def set_del_var(self):
        """sets the del_var attribute from the config file"""

        if not self.configfileexists:
            return

        try:
            with open(self.filename) as configfile:
                for line in configfile:
                    condense = line.replace(" ", "")
                    condense = condense.rstrip()
                    lcase = condense.lower()
                    if (
                        (len(condense) > 0)
                        and (condense[0] != "*")
                        and (lcase[:8] == "del_var_")
                        and (len(condense) > 8)
                    ):
                        self.del_var += [condense[8:]]
        except FileNotFoundError:
            print(f"Error: No config file named {self.filename}", file=stderr)
            self.configfileexists = False
            return

    def set_dictvar(self):
        """sets the dictvar attribute from config file"""

        if not self.configfileexists:
            return

        try:
            with open(self.filename) as configfile:
                for line in configfile:
                    condense = line.replace(" ", "")
                    condense = condense.rstrip()
                    lcase = condense.lower()
                    if len(condense) > 0 and (condense[0] != "*") and "=" in lcase:
                        varname = lcase[: lcase.find("=")]
                        auxvar = condense[condense.find("=") + 1 :]
                        if varname[:4] == "var_" and auxvar != "":
                            self.dictvar[varname[4:]] = auxvar
        except FileNotFoundError:
            print(f"Error: No config file named {self.filename}", file=stderr)
            self.configfileexists = False
            return

    def echo(self):
        """echos the values of the current class"""

        print()
        super().echo()

        print(f"no. allowed UNFEASIBLE points {self.no_allowed_unfeasible:d}")
        if self.create_itervar_diff:
            print("Set to create a summary file of the iteration variable values!")

        if self.add_ixc != []:
            print("add_ixc", self.add_ixc)
        if self.del_ixc != []:
            print("del_ixc", self.del_ixc)
        if self.add_icc != []:
            print("add_icc", self.add_icc)
        if self.del_icc != []:
            print("del_icc", self.del_icc)
        for key, value in self.dictvar.items():
            print(f"set {key}  to {value}")
        if self.del_var != []:
            print("del_var", self.del_var)

        print()
        sleep(1)

    def modify_in_dat(self):
        """modifies IN.DAT using the configuration parameters"""

        # Need to keep this order!
        # If bounds are modified in vars, but ixc is newly added,
        # bounds do not get put into IN.DAT. Hence, vars needs to be modified
        # first.
        self.modify_ixc()
        self.modify_icc()
        self.modify_vars()

    def modify_vars(self):
        """modifies IN.DAT by adding, deleting and modifiying variables"""

        in_dat = InDat()

        # add and modify variables
        for key in self.dictvar:
            set_variable_in_indat(in_dat, key, self.dictvar[key])

        # delete variables
        for key in self.del_var:
            key = key.lower()
            if "bound" in key:
                number = (key.split("("))[1].split(")")[0]
                if "boundu" in key:
                    in_dat.remove_bound(number, "u")
                else:
                    in_dat.remove_bound(number, "l")
            else:
                in_dat.remove_parameter(key)

        in_dat.write_in_dat(output_filename="IN.DAT")

    def modify_ixc(self):
        """modifies the array of iteration variables in IN.DAT"""

        # check that there is no variable in both lists
        if set(self.add_ixc).intersection(self.del_ixc) != set():
            print(
                "Error: You are trying to add and delete the same variable from ixc!",
                file=stderr,
            )
            exit()

        in_dat = InDat()

        for iter_var in self.add_ixc:
            in_dat.add_iteration_variable(int(iter_var))

        for iter_var in self.del_ixc:
            in_dat.remove_iteration_variable(int(iter_var))

        in_dat.write_in_dat(output_filename="IN.DAT")

    def modify_icc(self):
        """modifies the array of constraint equations in IN.DAT"""

        # check that there is no variable in both lists
        if set(self.add_icc).intersection(self.del_icc) != set():
            print(
                "Error: You are trying to add and delete the same variable from icc!",
                file=stderr,
            )
            exit()

        in_dat = InDat()

        for constr in self.add_icc:
            in_dat.add_constraint_equation(int(constr))

        for constr in self.del_icc:
            in_dat.remove_constraint_equation(int(constr))

        in_dat.write_in_dat(output_filename="IN.DAT")

no_allowed_unfeasible = 0 class-attribute instance-attribute

the number of allowed unfeasible points in a sweep

create_itervar_diff = False class-attribute instance-attribute

boolean to indicate the creation of a summary file of the iteration variable values at each stage

dictvar = {} class-attribute instance-attribute

Dictionary mapping variable name to new value (replaces old or gets appended)

del_var = [] class-attribute instance-attribute

List of variables to be deleted from IN.DAT

filename = filename instance-attribute

add_ixc = self.get_attribute_csv_list('add_ixc') class-attribute instance-attribute

List of iteration variables to be added to IN.DAT

del_ixc = self.get_attribute_csv_list('del_ixc') class-attribute instance-attribute

List of iteration variables to be deleted from IN.DAT

add_icc = self.get_attribute_csv_list('add_icc') class-attribute instance-attribute

List of constrained equations to be added to IN.DAT

del_icc = self.get_attribute_csv_list('del_icc') class-attribute instance-attribute

List of constrained equations to be deleted from IN.DAT

get_attribute_csv_list(attributename)

get class attribute list from configuration file expects comma separated values

Source code in process/core/io/process_config.py
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
def get_attribute_csv_list(self, attributename):
    """get class attribute list from configuration file
    expects comma separated values
    """

    if not self.configfileexists:
        return []

    try:
        with open(self.filename) as configfile:
            attribute_list = []

            for line in configfile:
                condense = line.replace(" ", "")
                condense = condense.rstrip()
                lcase = condense.lower()
                if (
                    (len(condense) > 0)
                    and (condense[0] != "*")
                    and (attributename == lcase[: len(attributename)])
                ):
                    buf = condense[condense.find("=") + 1 :].split(",")
                    if buf[-1] == "":  # if last value has ended on comma
                        buf = buf[:-1]
                    attribute_list += buf
    except FileNotFoundError:
        print(f"Error: No config file named {self.filename}", file=stderr)
        self.configfileexists = False
        return []
    return attribute_list

set_del_var()

sets the del_var attribute from the config file

Source code in process/core/io/process_config.py
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
def set_del_var(self):
    """sets the del_var attribute from the config file"""

    if not self.configfileexists:
        return

    try:
        with open(self.filename) as configfile:
            for line in configfile:
                condense = line.replace(" ", "")
                condense = condense.rstrip()
                lcase = condense.lower()
                if (
                    (len(condense) > 0)
                    and (condense[0] != "*")
                    and (lcase[:8] == "del_var_")
                    and (len(condense) > 8)
                ):
                    self.del_var += [condense[8:]]
    except FileNotFoundError:
        print(f"Error: No config file named {self.filename}", file=stderr)
        self.configfileexists = False
        return

set_dictvar()

sets the dictvar attribute from config file

Source code in process/core/io/process_config.py
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
def set_dictvar(self):
    """sets the dictvar attribute from config file"""

    if not self.configfileexists:
        return

    try:
        with open(self.filename) as configfile:
            for line in configfile:
                condense = line.replace(" ", "")
                condense = condense.rstrip()
                lcase = condense.lower()
                if len(condense) > 0 and (condense[0] != "*") and "=" in lcase:
                    varname = lcase[: lcase.find("=")]
                    auxvar = condense[condense.find("=") + 1 :]
                    if varname[:4] == "var_" and auxvar != "":
                        self.dictvar[varname[4:]] = auxvar
    except FileNotFoundError:
        print(f"Error: No config file named {self.filename}", file=stderr)
        self.configfileexists = False
        return

echo()

echos the values of the current class

Source code in process/core/io/process_config.py
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
def echo(self):
    """echos the values of the current class"""

    print()
    super().echo()

    print(f"no. allowed UNFEASIBLE points {self.no_allowed_unfeasible:d}")
    if self.create_itervar_diff:
        print("Set to create a summary file of the iteration variable values!")

    if self.add_ixc != []:
        print("add_ixc", self.add_ixc)
    if self.del_ixc != []:
        print("del_ixc", self.del_ixc)
    if self.add_icc != []:
        print("add_icc", self.add_icc)
    if self.del_icc != []:
        print("del_icc", self.del_icc)
    for key, value in self.dictvar.items():
        print(f"set {key}  to {value}")
    if self.del_var != []:
        print("del_var", self.del_var)

    print()
    sleep(1)

modify_in_dat()

modifies IN.DAT using the configuration parameters

Source code in process/core/io/process_config.py
434
435
436
437
438
439
440
441
442
443
def modify_in_dat(self):
    """modifies IN.DAT using the configuration parameters"""

    # Need to keep this order!
    # If bounds are modified in vars, but ixc is newly added,
    # bounds do not get put into IN.DAT. Hence, vars needs to be modified
    # first.
    self.modify_ixc()
    self.modify_icc()
    self.modify_vars()

modify_vars()

modifies IN.DAT by adding, deleting and modifiying variables

Source code in process/core/io/process_config.py
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
def modify_vars(self):
    """modifies IN.DAT by adding, deleting and modifiying variables"""

    in_dat = InDat()

    # add and modify variables
    for key in self.dictvar:
        set_variable_in_indat(in_dat, key, self.dictvar[key])

    # delete variables
    for key in self.del_var:
        key = key.lower()
        if "bound" in key:
            number = (key.split("("))[1].split(")")[0]
            if "boundu" in key:
                in_dat.remove_bound(number, "u")
            else:
                in_dat.remove_bound(number, "l")
        else:
            in_dat.remove_parameter(key)

    in_dat.write_in_dat(output_filename="IN.DAT")

modify_ixc()

modifies the array of iteration variables in IN.DAT

Source code in process/core/io/process_config.py
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
def modify_ixc(self):
    """modifies the array of iteration variables in IN.DAT"""

    # check that there is no variable in both lists
    if set(self.add_ixc).intersection(self.del_ixc) != set():
        print(
            "Error: You are trying to add and delete the same variable from ixc!",
            file=stderr,
        )
        exit()

    in_dat = InDat()

    for iter_var in self.add_ixc:
        in_dat.add_iteration_variable(int(iter_var))

    for iter_var in self.del_ixc:
        in_dat.remove_iteration_variable(int(iter_var))

    in_dat.write_in_dat(output_filename="IN.DAT")

modify_icc()

modifies the array of constraint equations in IN.DAT

Source code in process/core/io/process_config.py
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
def modify_icc(self):
    """modifies the array of constraint equations in IN.DAT"""

    # check that there is no variable in both lists
    if set(self.add_icc).intersection(self.del_icc) != set():
        print(
            "Error: You are trying to add and delete the same variable from icc!",
            file=stderr,
        )
        exit()

    in_dat = InDat()

    for constr in self.add_icc:
        in_dat.add_constraint_equation(int(constr))

    for constr in self.del_icc:
        in_dat.remove_constraint_equation(int(constr))

    in_dat.write_in_dat(output_filename="IN.DAT")