• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SPF-OST / pytrnsys / 11342368134

15 Oct 2024 08:37AM UTC coverage: 25.225% (+0.1%) from 25.085%
11342368134

push

github

web-flow
Merge pull request #208 from SPF-OST/number-eqs-automatically

Warn if declared number of equations (and constants, etc.) doesn't ma…

176 of 202 new or added lines in 7 files covered. (87.13%)

1 existing line in 1 file now uncovered.

3445 of 13657 relevant lines covered (25.23%)

0.25 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/pytrnsys/psim/processParallelTrnsys.py
1
# pylint: skip-file
2
# type: ignore
3

4
import dataclasses as _dc
×
5
import glob
×
6
import json
×
7
import logging as _log
×
8
import multiprocessing as mp
×
9
import os
×
10
import pathlib as _pl
×
11
import re
×
12
import traceback as _tb
×
13
import typing as _tp
×
14

15
import matplotlib.pyplot as plt
×
16
import numpy as num
×
17
import pandas as pd
×
18
import seaborn as _seb
×
19

20
import pytrnsys.costCalculation as _cc
×
21
import pytrnsys.plot.comparison as _pc
×
22
import pytrnsys.plot.plotMatplotlib as plot
×
23
import pytrnsys.psim.conditions as _conds
×
24
import pytrnsys.psim.debugProcess as debugProcess
×
25
import pytrnsys.psim.processTrnsysDf as processTrnsys
×
26
import pytrnsys.report.latexReport as latex
×
27
import pytrnsys.rsim.runParallel as run
×
28
import pytrnsys.trnsys_util.readConfigTrnsys as readConfig
×
29
import pytrnsys.utils.uncertainFloat as _uf
×
30

31
try:
×
32
    import pytrnsys_examples
×
33
except ImportError:
×
34
    pass
×
35
# we would need to pass the Class as inputs
36
import pytrnsys.utils.log as log
×
37

38

39
@_dc.dataclass
×
40
class _ProcessingCase:
×
41
    logger: _log.Logger
×
42
    processTrnsysDf: processTrnsys.ProcessTrnsysDf
×
43
    locationPath: str
×
44
    fileName: str
×
45
    inputs: _tp.Mapping[str, _tp.Any]
×
46
    individualFiles: _tp.Optional[_tp.Sequence[str]]
×
47
    yearReadInMonthlyFile: int
×
48

49
    def run(self) -> str:
×
50
        try:
×
51
            self._runImpl()
×
52
        except Exception as e:
×
53
            self.logger.error("An exception occurred processing case %s: %s", self.fileName, e)
×
54
            self.logger.error("Error trace:\n%s", _tb.format_exc())
×
55
            return f"{e}: {self.fileName}"
×
56

57
        return f"Finished: {self.fileName}"
×
58

59
    def _runImpl(self) -> None:
×
60
        self.processTrnsysDf.setInputs(self.inputs)
×
61
        if self.individualFiles is not None:
×
62
            self.processTrnsysDf.setIndividualFiles(self.individualFiles)
×
63
        if "latexNames" in self.inputs:
×
64
            self.processTrnsysDf.setLatexNamesFile(self.inputs["latexNames"])
×
65
        else:
66
            self.processTrnsysDf.setLatexNamesFile(None)
×
67
        if "matplotlibStyle" in self.inputs:
×
68
            self.processTrnsysDf.setMatplotlibStyle(self.inputs["matplotlibStyle"])
×
69
        if "setFontsize" in self.inputs:
×
70
            self.processTrnsysDf.setFontsize(self.inputs["setFontsize"])
×
71
        self.processTrnsysDf.setBuildingArea(self.inputs["buildingArea"])
×
72
        self.processTrnsysDf.setTrnsysDllPath(self.inputs["dllTrnsysPath"])
×
73
        self.processTrnsysDf.setPrintDataForGle(self.inputs["setPrintDataForGle"])
×
74
        self.processTrnsysDf.yearReadedInMonthylFile = self.yearReadInMonthlyFile
×
75
        self.processTrnsysDf.cleanModeLatex = self.inputs["cleanModeLatex"]
×
76
        if self.inputs["isTrnsys"]:
×
77
            self.processTrnsysDf.loadAndProcessTrnsys()
×
78
        else:
79
            self.processTrnsysDf.loadAndProcessGeneric()
×
80
        # rename files if multiple years are available:
81
        if self.yearReadInMonthlyFile != -1 and self.inputs["typeOfProcess"] != "json":
×
82
            renameFile = os.path.join(self.locationPath, self.fileName, self.fileName)
×
83

84
            fileEndingsDefault = ["-results.json", "-report.pdf", "-plots.html"]
×
85

86
            for ending in fileEndingsDefault:
×
87
                newEnding = "-Year%i" % self.yearReadInMonthlyFile + ending
×
88
                try:
×
89
                    if os.path.isfile(renameFile + newEnding):
×
90
                        os.remove(renameFile + newEnding)
×
91
                    os.rename(renameFile + ending, renameFile + newEnding)
×
92
                    os.remove(renameFile + ending)
×
93
                except OSError:
×
94
                    print(
×
95
                        "File %s already exists, and thus was not saved again, needs to be improved (either not processed, or actually replaced)"
96
                        % (renameFile + newEnding)
97
                    )
98

99

100
class ProcessParallelTrnsys:
×
101
    """
102
    Main class to process all TRNSYS results.
103
    We need to include in this class any processing Class
104
    customized for new projects
105
    Author : Daniel Carbonell
106
    Date   : 01-10-2018
107
    ToDo : remove processDataGshp and make it generic
108
    getBaseClass should be defined outside this function so that this class is not changet at all
109
    """
110

111
    def __init__(self):
×
112
        self.defaultInputs()
×
113
        self.filteredfolder = [".gle"]
×
114

115
        self.logger = log.getOrCreateCustomLogger("root", self.inputs["outputLevel"])
×
116

117
    def defaultInputs(self, pathBase=None):
×
118
        self.inputs = {}
×
119
        self.inputs["plotStyle"] = "line"
×
120
        self.inputs["isTrnsys"] = True
×
121
        self.inputs["processParallel"] = True
×
122
        self.inputs["avoidUser"] = False
×
123
        self.inputs["processQvsT"] = True
×
124
        self.inputs["cleanModeLatex"] = False
×
125
        self.inputs["maxMinAvoided"] = False
×
126
        self.inputs["yearReadedInMonthlyFile"] = -1
×
127
        self.inputs["process"] = True
×
128
        self.inputs["firstMonth"] = "January"  # 0=January 1=February 7=August
×
129
        self.inputs["reduceCpu"] = 2
×
130
        self.inputs["typeOfProcess"] = "completeFolder"  # "casesDefined"
×
NEW
131
        self.inputs["forceProcess"] = (
×
132
            True  # even if results file exist it proceess the results, otherwise it checks if it exists
133
        )
134
        if pathBase:
×
135
            self.inputs["pathBase"] = pathBase
×
136
        else:
137
            self.inputs["pathBase"] = os.getcwd()
×
138
        self.inputs["setPrintDataForGle"] = True
×
139
        self.inputs["firstConsideredTime"] = None  # Be carefull here. Thsi will not be proprly filtered
×
140
        self.inputs["buildingArea"] = 1072.0
×
141
        self.inputs["parseFileCreated"] = False
×
142
        self.inputs["dllTrnsysPath"] = False
×
143
        self.inputs["classProcessing"] = False
×
144
        self.inputs["latexExePath"] = "Unknown"
×
145
        self.inputs["figureFormat"] = "pdf"
×
146
        self.inputs["plotEmf"] = False
×
147
        self.inputs["outputLevel"] = "INFO"
×
148
        self.inputs["createLatexPdf"] = True
×
149
        self.inputs["calculateCost"] = False
×
150
        self.inputs["costPdf"] = False
×
151
        self.inputs["dailyBalance"] = False
×
152
        self.inputs["hourlyBalance"] = False
×
153
        self.inputs["calculateHeatDemand"] = True
×
154
        self.inputs["calculateSPF"] = True
×
155
        self.inputs["addWeightedSPF"] = False
×
156
        self.inputs["calculateElectricDemand"] = True
×
157
        self.inputs["extensionFig"] = ".png"
×
158
        self.inputs["comparePlotUserName"] = ""  # don't change this default value
×
159

160
        self.individualFile = False
×
161

162
    def setFilteredFolders(self, foldersNotUsed):
×
163
        self.filteredfolder = foldersNotUsed
×
164

165
    def readConfig(self, path, name, parseFileCreated=False):
×
166
        self.configPath = path
×
167
        tool = readConfig.ReadConfigTrnsys()
×
168
        tool.readFile(path, name, self.inputs, parseFileCreated=parseFileCreated)
×
169
        # self.inputs["pathBase"] = path
170
        self.logger.setLevel(self.inputs["outputLevel"])
×
171
        if "latexNames" in self.inputs.keys():
×
172
            if ":" not in self.inputs["latexNames"]:
×
173
                self.inputs["latexNames"] = os.path.join(self.configPath, self.inputs["latexNames"])
×
174
        if "fileToLoad" in self.inputs.keys():
×
175
            self.individualFile = True
×
176

177
    def _createProcessTrnsysDf(self, pathFolder: str, fileName: str) -> processTrnsys.ProcessTrnsysDf:
×
178
        return processTrnsys.ProcessTrnsysDf(pathFolder, fileName, individualFile=self.individualFile)
×
179

180
    def isStringNumber(self, sample):
×
181
        """
182
        Does a given string consist of a number only?
183

184
        Parameters
185
        ---------
186
        sample : str
187
            String to be checked
188

189
        Returns
190
        -------
191
        bool
192
            Indicates whether sample consists only of a number
193

194
        """
195
        try:
×
196
            float(sample)
×
197
            return True
×
198
        except ValueError:
×
199
            return False
×
200

201
    def loadPlotJson(self, filePath):
×
202
        with open(filePath, "r") as file:
×
203
            plotParDict = json.load(file)
×
204

205
        returnDict = {}
×
206

207
        pyplotKwargs = ""
×
208
        for entry in plotParDict:
×
209
            try:
×
210
                if isinstance(plotParDict[entry], str):
×
211
                    plotParDict[entry] = "'" + plotParDict[entry] + "'"
×
212
                plotStatement = "plt.plot(1.,1.," + entry + "=%s)" % plotParDict[entry]
×
213
                plt.figure()
×
214
                exec(plotStatement)
×
215
                plt.close()
×
216
                pyplotKwargs = pyplotKwargs + "," + entry + "=" + str(plotParDict[entry])
×
217
            except:
×
218
                pass
×
219
        return pyplotKwargs
×
220

221
    def process(self):
×
222
        processingCases = []
×
223
        fileName = []
×
224

225
        self.filesReturn = None
×
226

227
        if os.path.exists(os.path.join(self.inputs["pathBase"], "Summary.dat")):
×
228
            os.remove(os.path.join(self.inputs["pathBase"], "Summary.dat"))
×
229

230
        if (self.inputs["typeOfProcess"] == "completeFolder") or (self.inputs["typeOfProcess"] == "json"):
×
231
            pathFolder = self.inputs["pathBase"]
×
232

233
            if self.inputs["typeOfProcess"] == "completeFolder":
×
234
                files = glob.glob(os.path.join(pathFolder, "**/*.lst"), recursive=True)
×
235
                if not files:
×
236
                    self.logger.warning("No lst files in %s", pathFolder)
×
237
                fileName = [_pl.Path(name).parts[-2] for name in files]
×
238
                relPaths = [os.path.relpath(os.path.dirname(file), pathFolder) for file in files]
×
239

240
                self.filesReturn = files
×
241

242
            elif self.inputs["typeOfProcess"] == "json":
×
243
                files = glob.glob(os.path.join(pathFolder, "**/*.json"), recursive=True)
×
244
                fileName = [_pl.Path(name).parts[-2] for name in files]
×
245
                relPaths = [os.path.relpath(os.path.dirname(file), pathFolder) for file in files]
×
246
                relPaths = list(
×
247
                    dict.fromkeys(relPaths)
248
                )  # remove duplicates due to folders containing more than one json files
249

250
            for relPath in relPaths:
×
251
                if relPath == ".":
×
252
                    continue
×
253
                name = _pl.Path(relPath).parts[-1]
×
254
                folderUsed = True
×
255
                for i in range(len(self.filteredfolder)):
×
256
                    if name == self.filteredfolder[i]:
×
257
                        folderUsed = False
×
258
                if folderUsed:
×
259
                    nameWithPath = os.path.join(pathFolder, "%s\\%s-results.json" % (relPath, name))
×
260

261
                    if os.path.isfile(nameWithPath) and self.inputs["forceProcess"] == False:
×
262
                        self.logger.info("%s already processed" % name)
×
263

264
                    elif (
×
265
                        os.path.isfile(os.path.join(pathFolder, "%s\\%s-Year1-results.json" % (relPath, name)))
266
                        and self.inputs["forceProcess"] == False
267
                    ):
268
                        self.logger.info("%s already processed" % name)
×
269

270
                    else:
271
                        if len(_pl.Path(relPath).parts) > 1:
×
272
                            newPath = os.path.join(pathFolder, os.path.join(*list(_pl.Path(relPath).parts[:-1])))
×
273
                        else:
274
                            newPath = pathFolder
×
275
                        processTrnsysDf = self._createProcessTrnsysDf(newPath, name)
×
276

277
                        self.logger.info("%s will be processed" % name)
×
278
                        processingCase = self._createProcessingCase(processTrnsysDf, pathFolder, name)
×
279
                        processingCases.append(processingCase)
×
280

281
        elif self.inputs["typeOfProcess"] == "individual":
×
282
            self.individualFiles = []
×
283
            for file in self.inputs["fileToLoad"]:
×
284
                fileDict = {}
×
285
                fileDict["timeStep"] = file[0]
×
286
                fileDict["path"] = self.inputs[file[1]]
×
287
                fileDict["name"] = file[2]
×
288
                self.individualFiles += [fileDict]
×
289

290
            for fileDict in self.individualFiles:
×
291
                processTrnsysDf = self._createProcessTrnsysDf(fileDict["path"], fileDict["name"])
×
292
                self.logger.info("%s will be processed" % fileDict["name"])
×
293
                processingCase = self._createProcessingCase(
×
294
                    processTrnsysDf, fileDict["path"], fileDict["name"], self.individualFiles
295
                )
296
                processingCases.append(processingCase)
×
297

298
        elif self.inputs["typeOfProcess"] == "casesDefined":
×
299
            name = self.inputs["fileName"]
×
300
            pathFolder = self.inputs["pathBase"]
×
301
            processTrnsysDf = self._createProcessTrnsysDf(pathFolder, name)
×
302
            processingCase = self._createProcessingCase(processTrnsysDf, pathFolder, name)
×
303
            processingCases.append(processingCase)
×
304

305
            self.filesReturn = []
×
306
            self.filesReturn.append(os.path.join(pathFolder, name, name) + ".dck")
×
307

308
        elif self.inputs["typeOfProcess"] == "citiesFolder":
×
309
            for city in self.inputs["cities"]:
×
310
                pathFolder = os.path.join(self.inputs["pathBase"], city)
×
311
                fileName = [name for name in os.listdir(pathFolder) if os.path.isdir(pathFolder + "\\" + name)]
×
312

313
                for name in fileName:
×
314
                    folderUsed = True
×
315
                    for i in range(len(self.filteredfolder)):
×
316
                        if name == self.filteredfolder[i]:
×
317
                            folderUsed = False
×
318
                    if folderUsed:
×
319
                        nameWithPath = os.path.join(pathFolder, "%s\\%s-results.json" % (name, name))
×
320

321
                        if os.path.isfile(nameWithPath) and self.inputs["forceProcess"] == False:
×
322
                            self.logger.info("%s already processed" % name)
×
323

324
                        elif (
×
325
                            os.path.isfile(os.path.join(pathFolder, "%s\\%s-Year1-results.json" % (name, name)))
326
                            and self.inputs["forceProcess"] == False
327
                        ):
328
                            self.logger.info("%s already processed" % name)
×
329

330
                        else:
331
                            processTrnsysDf = self._createProcessTrnsysDf(pathFolder, name)
×
332

333
                            self.logger.info("%s will be processed" % name)
×
334

335
                            if ("hourly" in name or "hourlyOld" in name) and not "Mean" in name:
×
336
                                self._addCasesForYears(processTrnsysDf, pathFolder, name, processingCases)
×
337
                            else:
338
                                processingCase = self._createProcessingCase(processTrnsysDf, pathFolder, name)
×
339
                                processingCases.append(processingCase)
×
340

341
        elif self.inputs["typeOfProcess"] == "config":
×
342
            """
343
            Processes the files that are specified in the process.config file
344

345
            This option is to be used with the following arguments in the process.config file:
346

347
            stringArray cities
348
            stringArray fileTypes
349

350
            examples for cities:
351

352
            "GVE" "BER" "BAS" "SMA" "DAV" "OTL"
353

354
            examples for fileTypes:
355

356
            "sia" "hourly" "monthlyMean"
357
            """
358

359
            for city in self.inputs["cities"][0]:
×
360
                pathFolder = os.path.join(self.inputs["pathBase"], city)
×
361
                fileName = [name for name in os.listdir(pathFolder) if os.path.isdir(pathFolder + "\\" + name)]
×
362

363
                for name in fileName:
×
364
                    for type in self.inputs["fileTypes"][0]:
×
365
                        if type in name:
×
366
                            folderUsed = True
×
367
                            for i in range(len(self.filteredfolder)):
×
368
                                if name == self.filteredfolder[i]:
×
369
                                    folderUsed = False
×
370
                            if folderUsed:
×
371
                                nameWithPath = os.path.join(pathFolder, "%s\\%s-results.json" % (name, name))
×
372

373
                                if os.path.isfile(nameWithPath) and self.inputs["forceProcess"] == False:
×
374
                                    self.logger.info("file :%s already processed" % name)
×
375

376
                                elif (
×
377
                                    os.path.isfile(os.path.join(pathFolder, "%s\\%s-Year1-results.json" % (name, name)))
378
                                    and self.inputs["forceProcess"] == False
379
                                ):
380
                                    self.logger.info("file :%s already processed" % name)
×
381

382
                                else:
383
                                    processTrnsysDf = self._createProcessTrnsysDf(pathFolder, name)
×
384

385
                                    self.logger.info("%s will be processed" % name)
×
386

387
                                    if ("hourly" in name or "hourlyOld" in name) and not "Mean" in name:
×
388
                                        if self.inputs["forceHourlyYear"]:
×
389
                                            processingCase = self._createProcessingCase(
×
390
                                                processTrnsysDf, pathFolder, name
391
                                            )
392
                                            processingCases.append(processingCase)
×
393
                                        else:
394
                                            self._addCasesForYears(processTrnsysDf, pathFolder, name, processingCases)
×
395
                                    elif "hourlyMean" in name and type != "hourlyMean":
×
396
                                        pass
×
397
                                    else:
398
                                        processingCase = self._createProcessingCase(processTrnsysDf, pathFolder, name)
×
399
                                        processingCases.append(processingCase)
×
400
        else:
401
            raise ValueError("Not Implemented yet")
×
402

403
        typeOfProcess = self.inputs["typeOfProcess"]
×
404
        if self.inputs["processParallel"]:
×
405
            debug = debugProcess.DebugProcess(pathFolder, "FileProcessed.dat", fileName)
×
406
            debug.start()
×
407

408
            # maximum number of processes at once:
409
            maxNumberOfCPU = min(run.getNumberOfCPU() - self.inputs["reduceCpu"], len(fileName))
×
410

411
            pool = mp.Pool(processes=maxNumberOfCPU)
×
412

413
            results = pool.map(_ProcessingCase.run, processingCases)
×
414

415
            pool.close()
×
416
            pool.join()
×
417

418
            debug.addLines(results)
×
419
            debug.finish()
×
420
        else:
421
            for processingCase in processingCases:
×
422
                processingCase.run()
×
423

424
        if self.inputs["calculateCost"] and "cost" in self.inputs:
×
425
            fileNameList = [self.inputs["fileName"]] if typeOfProcess == "casesDefined" else None
×
426

427
            self.calcCost(fileNameList)
×
428

429
        if "pathInfoToJson" in self.inputs.keys():  # first add
×
430
            self.transferPathInfoToJson()
×
431

432
        if "acrossSetsCalc" in self.inputs.keys():
×
433
            self.logger.info("Calculating across sets")
×
434
            self.calculationsAcrossSets()
×
435

436
        if "comparePlot" in self.inputs or "comparePlotConditional" in self.inputs:
×
437
            self.logger.info("Generating comparison plots.")
×
438
            commands = self.inputs.get("comparePlotConditional", []) + self.inputs.get("comparePlot", [])
×
439
            self.plotComparison(commands, shallPlotUncertainties=False)
×
440

441
        if "comparePlotUncertain" in self.inputs:
×
442
            commands = self.inputs["comparePlotUncertain"]
×
443
            self.logger.info("Generating comparison plots with uncertainties.")
×
444
            self.plotComparison(commands, shallPlotUncertainties=True)
×
445

446
        if "barPlotConditional" in self.inputs.keys():
×
447
            self.logger.info("Generating conditional bar plot")
×
448
            self.plotBarplotConditional()
×
449

450
        if "boxPlot" in self.inputs or "boxPlotConditional" in self.inputs:
×
451
            self.logger.info("Generating box plot")
×
452
            self._plotBox()
×
453

454
        if "violinPlot" in self.inputs:
×
455
            self.logger.info("Generating violin plot")
×
456
            self._plotViolin()
×
457

458
        if "acrossSetsCalculationsPlot" in self.inputs.keys():
×
459
            self.logger.info("Generating plot of calculations across sets")
×
460
            self.plotCalculationsAcrossSets()
×
461

462
        if "scatterPlot" in self.inputs.keys():
×
463
            self.scatterPlot()
×
464

465
        if "jsonCalc" in self.inputs.keys():
×
466
            self.calculateInJson()
×
467

468
        if "jsonInsert" in self.inputs.keys():
×
469
            self.insertIntoJson()
×
470

471
        if "calcClimateCorrections" in self.inputs.keys():
×
472
            self.calculateClimateCorrections()
×
473

474
        if "compareMonthlyBarsPlot" in self.inputs.keys():
×
475
            self.plotMonthlyBarComparison()
×
476

477
        if "printBoxPlotGLEData" in self.inputs.keys():
×
478
            self.printBoxPlotGLEData()
×
479

480
        return self.filesReturn  # Dc maybe not the best way
×
481

482
    def _addCasesForYears(
×
483
        self,
484
        processTrnsysDf: processTrnsys.ProcessTrnsysDf,
485
        pathFolder: str,
486
        name: str,
487
        processingCases: list[_ProcessingCase],
488
    ) -> None:
489
        yearReadInMonthlyFileBase = self.inputs["yearReadedInMonthlyFile"]
×
490
        if yearReadInMonthlyFileBase == -1:
×
491
            yearReadInMonthlyFileBase = 0
×
492

493
        for i in range(self.inputs["numberOfYearsInHourlyFile"]):
×
494
            yearReadInMonthlyFile = yearReadInMonthlyFileBase + i
×
495
            processingCase = self._createProcessingCase(
×
496
                processTrnsysDf,
497
                pathFolder,
498
                name,
499
                yearReadInMonthlyFile=yearReadInMonthlyFile,
500
            )
501
            processingCases.append(processingCase)
×
502

503
    def _createProcessingCase(
×
504
        self,
505
        processTrnsyDf: processTrnsys.ProcessTrnsysDf,
506
        locationPath: str,
507
        fileName: str,
508
        individualFiles: _tp.Optional[_tp.Sequence[str]] = None,
509
        yearReadInMonthlyFile: int = -1,
510
    ) -> _ProcessingCase:
511
        return _ProcessingCase(
×
512
            self.logger, processTrnsyDf, locationPath, fileName, self.inputs, individualFiles, yearReadInMonthlyFile
513
        )
514

515
    def calculationsAcrossSets(self):
×
516
        pathFolder = self.inputs["pathBase"]
×
517
        for plotVariables in self.inputs["acrossSetsCalc"]:
×
518
            if len(plotVariables) < 4:
×
519
                raise ValueError(
×
520
                    "You did not specify variable names and labels for the x and the y Axis in a compare Plot line"
521
                )
522
            xAxisVariable = plotVariables[0]
×
523
            yAxisVariable = plotVariables[1]
×
524
            calculationVariable = plotVariables[2]
×
525

526
            conditionDict = {}
×
527
            equationDict = {}
×
528
            calcVariableDict = {}
×
529
            for plotVariable in plotVariables:
×
530
                if ":" in plotVariable:
×
531
                    conditionEntry, conditionValue = plotVariable.split(":")
×
532
                    conditionDict[conditionEntry] = conditionValue
×
533
                elif "=" in plotVariable:
×
534
                    equationVariable, equationExpression = plotVariable.split("=")
×
535
                    equationDict[equationVariable] = equationExpression
×
536
                    for variable in re.split(r"\W", equationExpression):
×
537
                        if variable != "" and not (self.isStringNumber(variable)):
×
538
                            calcVariableDict[variable] = ""
×
539

540
            plotXDict = {}
×
541
            plotYDict = {}
×
542

543
            if self.inputs["typeOfProcess"] == "json":
×
544
                resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"), recursive=True)
×
545
            else:
546
                resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"))
×
547

548
            xVariable = []
×
549

550
            for file in resultFiles:
×
551
                with open(file) as f_in:
×
552
                    resultsDict = json.load(f_in)
×
553
                    resultsDict[""] = None
×
554

555
                conditionList = []
×
556
                for conditionEntry in conditionDict:
×
557
                    entryClass = type(resultsDict[conditionEntry])
×
558
                    conditionDict[conditionEntry] = entryClass(conditionDict[conditionEntry])
×
559
                    conditionList.append(conditionDict[conditionEntry] == resultsDict[conditionEntry])
×
560

561
                if all(conditionList):
×
562
                    if "[" not in xAxisVariable:
×
563
                        xAxis = resultsDict[xAxisVariable]
×
564
                    else:
565
                        name, index = str(xAxisVariable).split("[")
×
566
                        index = int(index.replace("]", ""))
×
567
                        xAxis = resultsDict[name][index]
×
568
                    if "[" not in yAxisVariable:
×
569
                        yAxis = resultsDict[yAxisVariable]
×
570
                    else:
571
                        name, index = str(yAxisVariable).split("[")
×
572
                        index = int(index.replace("]", ""))
×
573
                        yAxis = resultsDict[name][index]
×
574

575
                    xVariable.append(xAxis)
×
576

577
                    chunkVariable = ""
×
578

579
                    if resultsDict[chunkVariable] not in plotXDict.keys():
×
580
                        plotXDict[resultsDict[chunkVariable]] = {}
×
581
                        plotYDict[resultsDict[chunkVariable]] = {}
×
582
                        plotXDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]] = [xAxis]
×
583
                        plotYDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]] = [yAxis]
×
584
                    elif resultsDict[calculationVariable] not in plotXDict[resultsDict[chunkVariable]].keys():
×
585
                        plotXDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]] = [xAxis]
×
586
                        plotYDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]] = [yAxis]
×
587
                    else:
588
                        plotXDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]].append(xAxis)
×
589
                        plotYDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]].append(yAxis)
×
590

591
                else:
592
                    pass
×
593

594
            for variable in calcVariableDict:
×
595
                calcVariableDict[variable] = num.array(plotYDict[None][variable])
×
596

597
            calcVariableDict["equationDict"] = equationDict
×
598
            for equation in equationDict:
×
599
                calcVariableDict["equation"] = equation
×
600
                exec("equationDict[equation]=" + equationDict[equation], calcVariableDict)
×
601

602
            xVariable = list(dict.fromkeys(xVariable))
×
603

604
            dataFrameDict = {}
×
605
            dataFrameDict[xAxisVariable] = xVariable
×
606
            dataFrameDict.update(equationDict)
×
607

608
            saveDf = pd.DataFrame(data=dataFrameDict)
×
609

610
            conditionsFileName = ""
×
611
            for conditionEntry in conditionDict:
×
612
                conditionsFileName += "_" + conditionEntry + "=" + str(conditionDict[conditionEntry])
×
613

614
            fileName = xAxisVariable + "_" + yAxisVariable + "_" + calculationVariable
×
615
            for equation in equationDict:
×
616
                fileName += "_" + equation
×
617
            fileName += conditionsFileName
×
618

619
            fullCsvPath = os.path.join(pathFolder, fileName + ".csv")
×
620
            saveDf.to_csv(fullCsvPath, index=False, sep=";")
×
621

622
    def plotComparison(self, commands, shallPlotUncertainties: bool):
×
623
        pathFolder = self.inputs["pathBase"]
×
624
        typeOfProcess = self.inputs["typeOfProcess"]
×
625
        logger = self.logger
×
626
        latexNames = self.inputs.get("latexNames")
×
627
        configPath = self.configPath
×
628
        stylesheet = self.inputs.get("matplotlibStyle")
×
629
        plotStyle = self.inputs["plotStyle"]
×
630
        comparePlotUserName = self.inputs["comparePlotUserName"]
×
631
        setPrintDataForGle = self.inputs["setPrintDataForGle"]
×
632
        extensionFig = self.inputs["extensionFig"]
×
633

634
        for plotVariables in commands:
×
635
            _pc.createPlot(
×
636
                plotVariables,
637
                pathFolder,
638
                logger,
639
                imageFileExtension=extensionFig,
640
                typeOfProcess=typeOfProcess,
641
                relativeLatexNamesFilePath=latexNames,
642
                configPath=configPath,
643
                stylesheetNameOrPath=stylesheet,
644
                plotStyle=plotStyle,
645
                comparePlotUserName=comparePlotUserName,
646
                shallPrintDataForGle=setPrintDataForGle,
647
                shallPlotUncertainties=shallPlotUncertainties,
648
            )
649

650
    def plotBarplotConditional(self):
×
651
        pathFolder = self.inputs["pathBase"]
×
652
        for plotVariables in self.inputs["barPlotConditional"]:
×
653
            if len(plotVariables) < 2:
×
654
                raise ValueError(
×
655
                    "You did not specify variable names and labels for the x and the y Axis in a compare Plot line"
656
                )
657
            xAxisVariable = plotVariables[0]
×
658
            yAxisVariable = plotVariables[1]
×
659
            chunkVariable = ""
×
660
            seriesVariable = ""
×
661
            if len(plotVariables) >= 3 and not (":" in plotVariables[2]):
×
662
                seriesVariable = plotVariables[2]
×
663
                chunkVariable = ""
×
664
            if len(plotVariables) >= 4 and not (":" in plotVariables[3]):
×
665
                chunkVariable = plotVariables[3]
×
666

667
            conditionDict = {}
×
668
            for plotVariable in plotVariables:
×
669
                if ":" in plotVariable:
×
670
                    conditionEntry, conditionValue = plotVariable.split(":")
×
671
                    conditionDict[conditionEntry] = conditionValue
×
672

673
            plotXDict = {}
×
674
            plotYDict = {}
×
675

676
            seriesColors = {}
×
677
            colorsCounter = 0
×
678
            colors = plt.rcParams["axes.prop_cycle"].by_key()["color"]
×
679

680
            if self.inputs["typeOfProcess"] == "json":
×
681
                resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"), recursive=True)
×
682
            else:
683
                resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"))
×
684

685
            conditionNeverMet = True
×
686

687
            for file in resultFiles:
×
688
                with open(file) as f_in:
×
689
                    resultsDict = json.load(f_in)
×
690
                    resultsDict[""] = None
×
691

692
                conditionList = []
×
693
                for conditionEntry in conditionDict:
×
694
                    entryClass = type(resultsDict[conditionEntry])
×
695
                    conditionDict[conditionEntry] = entryClass(conditionDict[conditionEntry])
×
696
                    conditionList.append(conditionDict[conditionEntry] == resultsDict[conditionEntry])
×
697

698
                if all(conditionList):
×
699
                    conditionNeverMet = False
×
700

701
                    if resultsDict[seriesVariable] not in seriesColors.keys():
×
702
                        seriesColors[resultsDict[seriesVariable]] = colors[colorsCounter]
×
703
                        colorsCounter += 1
×
704

705
                    if "[" not in xAxisVariable:
×
706
                        xAxis = resultsDict[xAxisVariable]
×
707
                    else:
708
                        name, index = str(xAxisVariable).split("[")
×
709
                        index = int(index.replace("]", ""))
×
710
                        xAxis = resultsDict[name][index]
×
711
                    if "[" not in yAxisVariable:
×
712
                        yAxis = resultsDict[yAxisVariable]
×
713
                    else:
714
                        name, index = str(yAxisVariable).split("[")
×
715
                        index = int(index.replace("]", ""))
×
716
                        yAxis = resultsDict[name][index]
×
717
                    if resultsDict[chunkVariable] not in plotXDict.keys():
×
718
                        plotXDict[resultsDict[chunkVariable]] = {}
×
719
                        plotYDict[resultsDict[chunkVariable]] = {}
×
720
                        plotXDict[resultsDict[chunkVariable]][resultsDict[seriesVariable]] = [xAxis]
×
721
                        plotYDict[resultsDict[chunkVariable]][resultsDict[seriesVariable]] = [yAxis]
×
722
                    elif resultsDict[seriesVariable] not in plotXDict[resultsDict[chunkVariable]].keys():
×
723
                        plotXDict[resultsDict[chunkVariable]][resultsDict[seriesVariable]] = [xAxis]
×
724
                        plotYDict[resultsDict[chunkVariable]][resultsDict[seriesVariable]] = [yAxis]
×
725
                    else:
726
                        plotXDict[resultsDict[chunkVariable]][resultsDict[seriesVariable]].append(xAxis)
×
727
                        plotYDict[resultsDict[chunkVariable]][resultsDict[seriesVariable]].append(yAxis)
×
728

729
                else:
730
                    pass
×
731

732
            if conditionNeverMet:
×
733
                self.logger.warning(
×
734
                    'The following conditions from "comparePlotConditional" were never met all at once:'
735
                )
736
                for entry in conditionDict:
×
737
                    self.logger.warning("%s = %s" % (entry, str(conditionDict[entry])))
×
738
                self.logger.warning("The respective plot cannot be generated")
×
739
                return
×
740

741
            self.doc = latex.LatexReport("", "")
×
742
            if "latexNames" in self.inputs.keys():
×
743
                if ":" in self.inputs["latexNames"]:
×
744
                    latexNameFullPath = self.inputs["latexNames"]
×
745
                else:
746
                    latexNameFullPath = os.path.join(self.configPath, self.inputs["latexNames"])
×
747
                self.doc.getLatexNamesDict(file=latexNameFullPath)
×
748
            else:
749
                self.doc.getLatexNamesDict()
×
750
            if "matplotlibStyle" in self.inputs.keys():
×
751
                stylesheet = self.inputs["matplotlibStyle"]
×
752
            else:
753
                stylesheet = "word.mplstyle"
×
754
            if stylesheet in plt.style.available:
×
755
                self.stylesheet = stylesheet
×
756
            else:
757
                root = os.path.dirname(os.path.abspath(__file__))
×
758
                self.stylesheet = os.path.join(root, r"..\\plot\\stylesheets", stylesheet)
×
759
            plt.style.use(self.stylesheet)
×
760

761
            fig1, ax1 = plt.subplots(constrained_layout=True, figsize=[8, 3], dpi=200)
×
762
            if self.inputs["plotStyle"] == "line":
×
763
                styles = ["x-", "x--", "x-.", "x:", "o-", "o--", "o-.", "o:"]
×
764
            elif self.inputs["plotStyle"] == "dot":
×
765
                styles = ["x", "o", "+", "d", "s", "v", "^", "h"]
×
766
            else:
767
                print("Invalid 'plotStyle' argument")
×
768

769
            dummy_lines = []
×
770
            chunkLabels = []
×
771
            labelSet = set()
×
772
            lines = ""
×
773
            for chunk, style in zip(plotXDict.keys(), styles):
×
774
                dummy_lines.append(ax1.plot([], [], style, c="black"))
×
775
                if chunk is not None:
×
776
                    if not isinstance(chunk, str):
×
777
                        chunkLabel = round(float(chunk), 2)
×
778
                        chunkLabels.append("{:.2f}".format(chunkLabel))
×
779
                    else:
780
                        chunkLabels.append(chunk)
×
781

782
                YBarPlot = []
×
783
                labelBarPlot = []
×
784
                keyBarPlot = []
×
785
                for key in plotXDict[chunk].keys():
×
786
                    index = num.argsort(plotXDict[chunk][key])
×
787
                    myX = num.array(plotXDict[chunk][key])[index]
×
788
                    myY = num.array(plotYDict[chunk][key])[index]
×
789

790
                    YBarPlot.append(myY)
×
791
                    mySize = len(myX)
×
792
                    XBase = num.arange(len(myX))
×
793
                    keyBarPlot.append(key)
×
794

795
                    if key is not None and not isinstance(key, str):
×
796
                        labelValue = round(float(key), 2)
×
797
                    elif key is not None:
×
798
                        labelValue = key
×
799
                    if key is not None and labelValue not in labelSet:
×
800
                        if not isinstance(labelValue, str):
×
801
                            label = "{0:.1f}".format(labelValue)
×
802
                            labelBarPlot.append(label)
×
803
                        else:
804
                            label = labelValue
×
805
                            label = self.doc.getNiceLatexNames(label)
×
806
                            labelBarPlot.append(label)
×
807

808
                    labelSet.add(labelValue)
×
809

810
                N = len(keyBarPlot)
×
811
                Number = num.arange(N)
×
812

813
                widthBarPlot = 1 / (N + 1)
×
814

815
                lines = "!%s\t" % "BarPlotData"
×
816
                line = "%s\t" % myX + "\n"
×
817
                lines = lines + line
×
818
                for n in Number:
×
819
                    nW = n - (N - 1) / 2
×
820
                    ax1.bar(
×
821
                        XBase + nW * widthBarPlot,
822
                        YBarPlot[n],
823
                        color=colors[n],
824
                        edgecolor="black",
825
                        width=widthBarPlot,
826
                        label=labelBarPlot[n],
827
                    )
828
                    line = "%s\t" % labelBarPlot[n]
×
829
                    lines = lines + line
×
830
                    line = "%s\t" % YBarPlot[n] + "\n"
×
831
                    lines = lines + line
×
832

833
            if 0:
×
834
                for X, Y in zip(myX, myY):
835
                    for chunk, style in zip(plotXDict.keys(), styles):
836
                        for key in plotXDict[chunk].keys():  # the varables that appear in the legend
837
                            index = num.argsort(plotXDict[chunk][key])
838
                            myX = num.array(plotXDict[chunk][key])[index]
839
                            myY = num.array(plotYDict[chunk][key])[index]
840
                            line = "%8.4f\t%8.4f\t" % (X, Y)
841
                            lines = lines + line
842

843
                    line = "\n"
844
                    lines = lines + line
845
            else:
846
                for i in range(mySize):
×
847
                    for chunk, style in zip(plotXDict.keys(), styles):
×
848
                        for key in plotXDict[chunk].keys():  # the varables that appear in the legend
×
849
                            index = num.argsort(plotXDict[chunk][key])
×
850
                            myX = num.array(plotXDict[chunk][key])[index]
×
851
                            myY = num.array(plotYDict[chunk][key])[index]
×
852

853
                            if len(myX) < i - 1:
×
854
                                if type(myX[i]) == num.str_ and type(myY[i]) == num.str_:
×
855
                                    line = myX[i] + "\t" + myY[i] + "\t"
×
856
                                elif type(myX[i]) == num.str_:
×
857
                                    line = myX[i] + "\t" + "%8.4f\t" % myY[i]
×
858
                                elif type(myY[i]) == num.str_:
×
859
                                    line = "%8.4f\t" % myX[i] + myX[i] + "\t"
×
860
                                else:
861
                                    line = "%8.4f\t%8.4f\t" % (myX[i], myY[i])
×
862
                                lines = lines + line
×
863

864
                    line = "\n"
×
865
                    lines = lines + line
×
866

867
            # box = ax1.get_position()
868
            # ax1.set_position([box.x0, box.y0, box.width, box.height])
869

870
            if chunkVariable != "":
×
871
                legend2 = fig1.legend(
×
872
                    [dummy_line[0] for dummy_line in dummy_lines],
873
                    chunkLabels,
874
                    title=self.doc.getNiceLatexNames(chunkVariable),
875
                    bbox_to_anchor=(1.5, 1.0),
876
                    bbox_transform=ax1.transAxes,
877
                )
878

879
            else:
880
                legend2 = None
×
881
            if seriesVariable != "":
×
882
                legend1 = fig1.legend(
×
883
                    title=self.doc.getNiceLatexNames(seriesVariable),
884
                    bbox_to_anchor=(1.15, 1.0),
885
                    bbox_transform=ax1.transAxes,
886
                )
887

888
            else:
889
                legend1 = None
×
890
            ax1.set_xlabel(self.doc.getNiceLatexNames(xAxisVariable))
×
891
            ax1.set_ylabel(self.doc.getNiceLatexNames(yAxisVariable))
×
892
            ax1.set_xticks(XBase)
×
893
            ax1.set_xticklabels(myX)
×
894

895
            fig2, ax2 = plt.subplots(constrained_layout=True, figsize=[8, 3], dpi=200)
×
896

897
            width2 = 0.33
×
898
            ax2.bar(
×
899
                XBase - 0.165,
900
                (YBarPlot[0] - YBarPlot[2]) / YBarPlot[2] * 100,
901
                color=colors[0],
902
                edgecolor="black",
903
                width=width2,
904
                label=labelBarPlot[0],
905
            )
906
            ax2.bar(
×
907
                XBase + 0.165,
908
                (YBarPlot[1] - YBarPlot[2]) / YBarPlot[2] * 100,
909
                color=colors[1],
910
                edgecolor="black",
911
                width=width2,
912
                label=labelBarPlot[1],
913
            )
914

915
            if chunkVariable != "":
×
916
                legend2 = fig2.legend(
×
917
                    [dummy_line[0] for dummy_line in dummy_lines],
918
                    chunkLabels,
919
                    title=self.doc.getNiceLatexNames(chunkVariable),
920
                    bbox_to_anchor=(1.5, 1.0),
921
                    bbox_transform=ax2.transAxes,
922
                )
923

924
            else:
925
                legend2 = None
×
926
            if seriesVariable != "":
×
927
                legend1 = fig2.legend(
×
928
                    title=self.doc.getNiceLatexNames(seriesVariable),
929
                    bbox_to_anchor=(1.15, 1.0),
930
                    bbox_transform=ax2.transAxes,
931
                )
932

933
            else:
934
                legend1 = None
×
935

936
            ax2.set_xlabel(self.doc.getNiceLatexNames(xAxisVariable))
×
937
            ax2.set_ylabel(self.doc.getNiceLatexNames(yAxisVariable) + "[%]")
×
938
            ax2.set_xticks(XBase)
×
939
            ax2.set_xticklabels(myX)
×
940

941
            conditionsFileName = "Barplot"
×
942
            if len(conditionDict) == 1:
×
943
                conditionName = self.doc.getNiceLatexNames(sorted(conditionDict)[0])
×
944
                ax1.set_title(conditionName + " = " + str(conditionDict[sorted(conditionDict)[0]]))
×
945
                conditionsFileName = sorted(conditionDict)[0] + "=" + str(conditionDict[sorted(conditionDict)[0]])
×
946
            else:
947
                conditionsTitle = ""
×
948
                for conditionEntry in conditionDict:
×
949
                    conditionName = self.doc.getNiceLatexNames(conditionEntry)
×
950
                    conditionsTitle += conditionName + " = " + str(conditionDict[conditionEntry]) + ", "
×
951
                    conditionsFileName += conditionEntry + "=" + str(conditionDict[conditionEntry]) + "_"
×
952
                conditionsTitle = conditionsTitle[:-2]
×
953
                ax1.set_title(conditionsTitle)
×
954
                conditionsFileName = conditionsFileName[:-1]
×
955
            # if chunkVariable is not '':
956
            #
957
            if legend2 is not None:
×
958
                fig1.add_artist(legend2)
×
959
            # fig1.canvas.draw()
960
            # if legend2 is not None:
961
            #    ax1.add_artist(legend2)
962
            #    legend2.set_in_layout(True)
963
            # if legend1 is not None:
964
            #    legend1.set_in_layout(True)
965
            if chunkVariable == "":
×
966
                fileName = xAxisVariable + "_" + yAxisVariable + "_" + seriesVariable + "_" + conditionsFileName
×
967
            else:
968
                fileName = (
×
969
                    xAxisVariable
970
                    + "_"
971
                    + yAxisVariable
972
                    + "_"
973
                    + seriesVariable
974
                    + "_"
975
                    + chunkVariable
976
                    + "_"
977
                    + conditionsFileName
978
                )
979
            fig1.savefig(os.path.join(pathFolder, fileName + e), bbox_inches="tight")
×
980
            plt.close()
×
981

982
            fig2.savefig(os.path.join(pathFolder, "diffPlot" + fileName + ".png"), bbox_inches="tight")
×
983
            plt.close()
×
984

985
            if self.inputs["setPrintDataForGle"]:
×
986
                outfile = open(os.path.join(pathFolder, fileName + ".dat"), "w")
×
987
                outfile.writelines(lines)
×
988
                outfile.close()
×
989

990
    def _plotViolin(self):
×
991
        allPlotVariables = self.inputs["violinPlot"]
×
992
        for plotVariables in allPlotVariables:
×
993
            self._plotBoxOrViolin(plotVariables, shallPlotViolin=True)
×
994

995
    def _plotBox(self):
×
996
        allPlotVariables = self.inputs.get("boxPlot", []) + self.inputs.get("boxPlotConditional", [])
×
997
        for plotVariables in allPlotVariables:
×
998
            self._plotBoxOrViolin(plotVariables, shallPlotViolin=False)
×
999

1000
    def _plotBoxOrViolin(self, plotVariables, shallPlotViolin):
×
1001
        pathFolder = self.inputs["pathBase"]
×
1002
        extensionFig = self.inputs["extensionFig"]
×
1003

1004
        if len(plotVariables) == 0:
×
1005
            raise ValueError("You must specify a variable name for the values for the box plot.")
×
1006

1007
        yAxisVariable = plotVariables[0]
×
1008
        chunkVariable = ""
×
1009
        seriesVariable = ""
×
1010
        serializedConditions = plotVariables[1:]
×
1011
        if len(plotVariables) >= 2 and not _conds.mayBeSerializedCondition(plotVariables[1]):
×
1012
            seriesVariable = plotVariables[1]
×
1013
            serializedConditions = plotVariables[2:]
×
1014
        if len(plotVariables) >= 3 and not _conds.mayBeSerializedCondition(plotVariables[2]):
×
1015
            chunkVariable = plotVariables[2]
×
1016
            serializedConditions = plotVariables[3:]
×
1017

1018
        conditions = _conds.createConditions(serializedConditions)
×
1019

1020
        plotYDict = {}
×
1021

1022
        seriesColors = {}
×
1023
        colorsCounter = 0
×
1024
        colors = plt.rcParams["axes.prop_cycle"].by_key()["color"]
×
1025

1026
        if self.inputs["typeOfProcess"] == "json":
×
1027
            resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"), recursive=True)
×
1028
        else:
1029
            resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"))
×
1030

1031
        conditionNeverMet = True
×
1032

1033
        for file in resultFiles:
×
1034
            with open(file) as f_in:
×
1035
                resultsDict = json.load(f_in)
×
1036
                resultsDict[""] = None
×
1037

1038
            conditionsFulfilled = conditions.doResultsSatisfyConditions(resultsDict)
×
1039

1040
            if conditionsFulfilled:
×
1041
                conditionNeverMet = False
×
1042

1043
                if resultsDict[seriesVariable] not in seriesColors.keys():
×
1044
                    seriesColors[resultsDict[seriesVariable]] = colors[colorsCounter]
×
1045
                    colorsCounter += 1
×
1046
                    colorsCounter = colorsCounter % len(colors)
×
1047

1048
                if "[" not in yAxisVariable:
×
1049
                    yAxis = resultsDict[yAxisVariable]
×
1050
                else:
1051
                    name, index = str(yAxisVariable).split("[")
×
1052
                    index = int(index.replace("]", ""))
×
1053
                    yAxis = resultsDict[name][index]
×
1054

1055
                if isinstance(yAxis, dict):
×
1056
                    uncertainFloat: _uf.UncertainFloat = _uf.UncertainFloat.from_dict(yAxis)
×
1057
                    yAxis = uncertainFloat.mean
×
1058

1059
                if resultsDict[chunkVariable] not in plotYDict.keys():
×
1060
                    plotYDict[resultsDict[chunkVariable]] = {}
×
1061
                    plotYDict[resultsDict[chunkVariable]][resultsDict[seriesVariable]] = [yAxis]
×
1062
                elif resultsDict[seriesVariable] not in plotYDict[resultsDict[chunkVariable]].keys():
×
1063
                    plotYDict[resultsDict[chunkVariable]][resultsDict[seriesVariable]] = [yAxis]
×
1064
                else:
1065
                    plotYDict[resultsDict[chunkVariable]][resultsDict[seriesVariable]].append(yAxis)
×
1066

1067
            else:
1068
                pass
×
1069

1070
        if conditionNeverMet:
×
1071
            self.logger.warning('The following conditions from "plotBoxConditional" were never met all at once:')
×
1072
            for condition in conditions.conditions:
×
1073
                self.logger.warning(condition)
×
1074
            self.logger.warning("The respective plot cannot be generated")
×
1075
            return
×
1076

1077
        self.doc = latex.LatexReport("", "")
×
1078
        if "latexNames" in self.inputs.keys():
×
1079
            if ":" in self.inputs["latexNames"]:
×
1080
                latexNameFullPath = self.inputs["latexNames"]
×
1081
            else:
1082
                latexNameFullPath = os.path.join(self.configPath, self.inputs["latexNames"])
×
1083
            self.doc.getLatexNamesDict(file=latexNameFullPath)
×
1084
        else:
1085
            self.doc.getLatexNamesDict()
×
1086
        if "matplotlibStyle" in self.inputs.keys():
×
1087
            stylesheet = self.inputs["matplotlibStyle"]
×
1088
        else:
1089
            stylesheet = "word.mplstyle"
×
1090
        if stylesheet in plt.style.available:
×
1091
            self.stylesheet = stylesheet
×
1092
        else:
1093
            root = os.path.dirname(os.path.abspath(__file__))
×
1094
            self.stylesheet = os.path.join(root, r"..\\plot\\stylesheets", stylesheet)
×
1095
        plt.style.use(self.stylesheet)
×
1096

1097
        fig1, ax1 = plt.subplots(constrained_layout=True)
×
1098
        if self.inputs["plotStyle"] == "line":
×
1099
            styles = ["x-", "x--", "x-.", "x:", "o-", "o--", "o-.", "o:"]
×
1100
        elif self.inputs["plotStyle"] == "dot":
×
1101
            styles = ["x", "o", "+", "d", "s", "v", "^", "h"]
×
1102
        else:
1103
            print("Invalid 'plotStyle' argument")
×
1104

1105
        dummy_lines = []
×
1106
        chunkLabels = []
×
1107

1108
        myY = []
×
1109
        for chunk, style in zip(plotYDict.keys(), styles):
×
1110
            dummy_lines.append(ax1.plot([], [], style, c="black"))
×
1111
            if chunk is not None:
×
1112
                if not isinstance(chunk, str):
×
1113
                    chunkLabel = round(float(chunk), 2)
×
1114
                    chunkLabels.append("{:.2f}".format(chunkLabel))
×
1115
                else:
1116
                    chunkLabels.append(chunk)
×
1117

1118
            for key in plotYDict[chunk].keys():
×
1119
                sortedSeriesYs = num.sort(plotYDict[chunk][key])
×
1120

1121
                myY.append(sortedSeriesYs)
×
1122

1123
        cityName = []
×
1124
        for chunk, style in zip(plotYDict.keys(), styles):
×
1125
            for key in plotYDict[chunk].keys():
×
1126
                if type(key) == str:
×
1127
                    keyNice = self.doc.getNiceLatexNames(key)
×
1128
                    cityName.append(keyNice)
×
1129
                else:
1130
                    cityName.append(key)
×
1131

1132
        if shallPlotViolin:
×
1133
            _seb.violinplot(data=myY, split=True, scale="area", inner="quartile", ax=ax1)
×
1134
        else:
1135
            ax1.boxplot(myY, showfliers=False)
×
1136

1137
        ax1.set_xticklabels(cityName)
×
1138

1139
        ax1.set_ylabel(self.doc.getNiceLatexNames(yAxisVariable))
×
1140

1141
        conditionsFileName = ""
×
1142
        conditionsTitle = ""
×
1143
        for condition in conditions.conditions:
×
1144
            conditionsFileName += condition.serializedCondition
×
1145
            if conditionsTitle != "":
×
1146
                conditionsTitle += ", " + condition.serializedCondition
×
1147
            else:
1148
                conditionsTitle += condition.serializedCondition
×
1149

1150
        conditionsTitle = conditionsTitle.replace("RANGE", "")
×
1151
        conditionsTitle = conditionsTitle.replace("LIST", "")
×
1152

1153
        conditionsFileName = conditionsFileName.replace("==", "=")
×
1154
        conditionsFileName = conditionsFileName.replace(">", "_g_")
×
1155
        conditionsFileName = conditionsFileName.replace("<", "_l_")
×
1156
        conditionsFileName = conditionsFileName.replace(">=", "_ge_")
×
1157
        conditionsFileName = conditionsFileName.replace("<=", "_le_")
×
1158
        conditionsFileName = conditionsFileName.replace("|", "_o_")
×
1159
        conditionsFileName = conditionsFileName.replace("RANGE:", "")
×
1160
        conditionsFileName = conditionsFileName.replace("LIST:", "")
×
1161

1162
        ax1.set_title(conditionsTitle)
×
1163

1164
        possibleFileNameComponents = [yAxisVariable, seriesVariable, chunkVariable, conditionsFileName]
×
1165
        fileNameComponents = [c for c in possibleFileNameComponents if c]
×
1166
        fileName = "_".join(fileNameComponents)
×
1167

1168
        fileNamePrefix = "ViolinPlot" if shallPlotViolin else "BoxPlot"
×
1169

1170
        fig1.savefig(os.path.join(pathFolder, f"{fileNamePrefix}_{fileName}_{extensionFig}"), bbox_inches="tight")
×
1171
        plt.close()
×
1172

1173
    def plotCalculationsAcrossSets(self):
×
1174
        pathFolder = self.inputs["pathBase"]
×
1175
        for plotVariables in self.inputs["acrossSetsCalculationsPlot"]:
×
1176
            if len(plotVariables) < 4:
×
1177
                raise ValueError(
×
1178
                    "You did not specify variable names and labels for the x and the y Axis in a compare Plot line"
1179
                )
1180
            xAxisVariable = plotVariables[0]
×
1181
            yAxisVariable = plotVariables[1]
×
1182
            calculationVariable = plotVariables[2]
×
1183

1184
            conditionDict = {}
×
1185
            equationDict = {}
×
1186
            calcVariableDict = {}
×
1187
            for plotVariable in plotVariables:
×
1188
                if ":" in plotVariable:
×
1189
                    conditionEntry, conditionValue = plotVariable.split(":")
×
1190
                    conditionDict[conditionEntry] = conditionValue
×
1191
                elif "=" in plotVariable:
×
1192
                    equationVariable, equationExpression = plotVariable.split("=")
×
1193
                    equationDict[equationVariable] = equationExpression
×
1194
                    for variable in re.split(r"\W", equationExpression):
×
1195
                        if variable != "" and not (self.isStringNumber(variable)):
×
1196
                            calcVariableDict[variable] = ""
×
1197

1198
            plotXDict = {}
×
1199
            plotYDict = {}
×
1200

1201
            seriesColors = {}
×
1202
            colorsCounter = 0
×
1203
            colors = plt.rcParams["axes.prop_cycle"].by_key()["color"]
×
1204

1205
            if self.inputs["typeOfProcess"] == "json":
×
1206
                resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"), recursive=True)
×
1207
            else:
1208
                resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"))
×
1209

1210
            for file in resultFiles:
×
1211
                with open(file) as f_in:
×
1212
                    resultsDict = json.load(f_in)
×
1213
                    resultsDict[""] = None
×
1214

1215
                conditionList = []
×
1216
                for conditionEntry in conditionDict:
×
1217
                    entryClass = type(resultsDict[conditionEntry])
×
1218
                    conditionDict[conditionEntry] = entryClass(conditionDict[conditionEntry])
×
1219
                    conditionList.append(conditionDict[conditionEntry] == resultsDict[conditionEntry])
×
1220

1221
                if all(conditionList):
×
1222
                    # if equationVariable not in seriesColors.keys():
1223
                    #    seriesColors[equationVariable] = colors[colorsCounter]
1224
                    #    colorsCounter += 1
1225

1226
                    if "[" not in xAxisVariable:
×
1227
                        xAxis = resultsDict[xAxisVariable]
×
1228
                    else:
1229
                        name, index = str(xAxisVariable).split("[")
×
1230
                        index = int(index.replace("]", ""))
×
1231
                        xAxis = resultsDict[name][index]
×
1232
                    if "[" not in yAxisVariable:
×
1233
                        yAxis = resultsDict[yAxisVariable]
×
1234
                    else:
1235
                        name, index = str(yAxisVariable).split("[")
×
1236
                        index = int(index.replace("]", ""))
×
1237
                        yAxis = resultsDict[name][index]
×
1238

1239
                    chunkVariable = ""
×
1240

1241
                    if resultsDict[chunkVariable] not in plotXDict.keys():
×
1242
                        plotXDict[resultsDict[chunkVariable]] = {}
×
1243
                        plotYDict[resultsDict[chunkVariable]] = {}
×
1244
                        plotXDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]] = [xAxis]
×
1245
                        plotYDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]] = [yAxis]
×
1246
                    elif resultsDict[calculationVariable] not in plotXDict[resultsDict[chunkVariable]].keys():
×
1247
                        plotXDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]] = [xAxis]
×
1248
                        plotYDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]] = [yAxis]
×
1249
                    else:
1250
                        plotXDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]].append(xAxis)
×
1251
                        plotYDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]].append(yAxis)
×
1252

1253
                else:
1254
                    pass
×
1255

1256
            for variable in calcVariableDict:
×
1257
                calcVariableDict[variable] = num.array(plotYDict[None][variable])
×
1258

1259
            calcVariableDict["equationDict"] = equationDict
×
1260
            for equation in equationDict:
×
1261
                calcVariableDict["equation"] = equation
×
1262
                exec("equationDict[equation]=" + equationDict[equation], calcVariableDict)
×
1263
                seriesColors[equation] = colors[colorsCounter]
×
1264
                colorsCounter += 1
×
1265
                colorsCounter = colorsCounter % len(colors)
×
1266

1267
            self.doc = latex.LatexReport("", "")
×
1268
            if "latexNames" in self.inputs.keys():
×
1269
                if ":" in self.inputs["latexNames"]:
×
1270
                    latexNameFullPath = self.inputs["latexNames"]
×
1271
                else:
1272
                    latexNameFullPath = os.path.join(self.configPath, self.inputs["latexNames"])
×
1273
                self.doc.getLatexNamesDict(file=latexNameFullPath)
×
1274
            else:
1275
                self.doc.getLatexNamesDict()
×
1276
            if "matplotlibStyle" in self.inputs.keys():
×
1277
                stylesheet = self.inputs["matplotlibStyle"]
×
1278
            else:
1279
                stylesheet = "word.mplstyle"
×
1280
            if stylesheet in plt.style.available:
×
1281
                self.stylesheet = stylesheet
×
1282
            else:
1283
                root = os.path.dirname(os.path.abspath(__file__))
×
1284
                self.stylesheet = os.path.join(root, r"..\\plot\\stylesheets", stylesheet)
×
1285
            plt.style.use(self.stylesheet)
×
1286

1287
            fig1, ax1 = plt.subplots(constrained_layout=True)
×
1288
            if self.inputs["plotStyle"] == "line":
×
1289
                styles = ["x-", "x--", "x-.", "x:", "o-", "o--", "o-.", "o:"]
×
1290
            elif self.inputs["plotStyle"] == "dot":
×
1291
                styles = ["x", "o", "+", "d", "s", "v", "^", "h"]
×
1292
            else:
1293
                print("Invalid 'plotStyle' argument")
×
1294

1295
            dummy_lines = []
×
1296
            chunkLabels = []
×
1297
            labelSet = set()
×
1298
            lines = ""
×
1299
            for chunk, style in zip(plotXDict.keys(), styles):
×
1300
                dummy_lines.append(ax1.plot([], [], style, c="black"))
×
1301
                if chunk is not None:
×
1302
                    if not isinstance(chunk, str):
×
1303
                        chunkLabel = round(float(chunk), 2)
×
1304
                        chunkLabels.append("{:.2f}".format(chunkLabel))
×
1305
                    else:
1306
                        chunkLabels.append(chunk)
×
1307

1308
                globalXAxisVariable = list(plotXDict[chunk].keys())[0]
×
1309
                index = num.argsort(plotXDict[chunk][globalXAxisVariable])
×
1310
                myX = num.array(plotXDict[chunk][globalXAxisVariable])[index]
×
1311
                mySize = len(myX)
×
1312

1313
                for key in equationDict.keys():
×
1314
                    myY = equationDict[key]
×
1315

1316
                    if key is not None and not isinstance(key, str):
×
1317
                        labelValue = round(float(key), 2)
×
1318
                    elif key is not None:
×
1319
                        labelValue = key
×
1320
                    if key is not None and labelValue not in labelSet:
×
1321
                        if not isinstance(labelValue, str):
×
1322
                            label = "{0:.1f}".format(labelValue)
×
1323
                        else:
1324
                            label = labelValue
×
1325
                            label = self.doc.getNiceLatexNames(label)
×
1326

1327
                        if "plotStyleJson" in self.inputs:
×
1328
                            plotKwargs = self.loadPlotJson(self.inputs["plotStyleJson"])
×
1329
                            plotStatement = (
×
1330
                                "ax1.plot(myX, myY,style, color=seriesColors[key], label=label" + plotKwargs + ")"
1331
                            )
1332
                            exec(plotStatement)
×
1333
                        else:
1334
                            ax1.plot(myX, myY, style, color=seriesColors[key], label=label)
×
1335
                    else:
1336
                        ax1.plot(myX, myY, style, color=seriesColors[key])
×
1337

1338
                    # for i in range(len(myX)):
1339
                    #     line="%8.4f\t%8.4f\n"%(myX[i],myY[i]);lines=lines+line
1340
            lines = "!%s\t" % calculationVariable
×
1341
            for chunk, style in zip(plotXDict.keys(), styles):
×
1342
                for key in equationDict.keys():  # the varables that appear in the legend
×
1343
                    line = "%s\t" % key
×
1344
                    lines = lines + line
×
1345
                line = "\n"
×
1346
                lines = lines + line
×
1347

1348
            for i in range(mySize):
×
1349
                for chunk, style in zip(plotXDict.keys(), styles):
×
1350
                    index = num.argsort(plotXDict[chunk][globalXAxisVariable])
×
1351
                    myX = num.array(plotXDict[chunk][globalXAxisVariable])[index]
×
1352
                    for key in equationDict.keys():  # the varables that appear in the legend
×
1353
                        myY = equationDict[key][index]
×
1354

1355
                        if type(myX[i]) == num.str_ and type(myY[i]) == num.str_:
×
1356
                            line = myX[i] + "\t" + myY[i] + "\t"
×
1357
                        elif type(myX[i]) == num.str_:
×
1358
                            line = myX[i] + "\t" + "%8.4f\t" % myY[i]
×
1359
                        elif type(myY[i]) == num.str_:
×
1360
                            line = "%8.4f\t" % myX[i] + myX[i] + "\t"
×
1361
                        else:
1362
                            line = "%8.4f\t%8.4f\t" % (myX[i], myY[i])
×
1363
                        lines = lines + line
×
1364

1365
                line = "\n"
×
1366
                lines = lines + line
×
1367

1368
            if chunkVariable != "":
×
1369
                legend2 = fig1.legend(
×
1370
                    [dummy_line[0] for dummy_line in dummy_lines],
1371
                    chunkLabels,
1372
                    title=self.doc.getNiceLatexNames(chunkVariable),
1373
                    bbox_to_anchor=(1.5, 1.0),
1374
                    bbox_transform=ax1.transAxes,
1375
                )
1376

1377
            else:
1378
                legend2 = None
×
1379
            if calculationVariable != "":
×
1380
                legend1 = fig1.legend(
×
1381
                    title=self.doc.getNiceLatexNames(calculationVariable),
1382
                    bbox_to_anchor=(1.2, 1.0),
1383
                    bbox_transform=ax1.transAxes,
1384
                )
1385

1386
            else:
1387
                legend1 = None
×
1388
            ax1.set_xlabel(self.doc.getNiceLatexNames(xAxisVariable))
×
1389
            ax1.set_ylabel(self.doc.getNiceLatexNames(yAxisVariable))
×
1390

1391
            conditionsFileName = ""
×
1392
            if len(conditionDict) == 1:
×
1393
                conditionName = self.doc.getNiceLatexNames(sorted(conditionDict)[0])
×
1394
                ax1.set_title(conditionName + " = " + str(conditionDict[sorted(conditionDict)[0]]))
×
1395
                conditionsFileName = sorted(conditionDict)[0] + "=" + str(conditionDict[sorted(conditionDict)[0]])
×
1396
            else:
1397
                conditionsTitle = ""
×
1398
                for conditionEntry in conditionDict:
×
1399
                    conditionName = self.doc.getNiceLatexNames(conditionEntry)
×
1400
                    conditionsTitle += conditionName + " = " + str(conditionDict[conditionEntry]) + ", "
×
1401
                    conditionsFileName += conditionEntry + "=" + str(conditionDict[conditionEntry]) + "_"
×
1402
                conditionsTitle = conditionsTitle[:-2]
×
1403
                ax1.set_title(conditionsTitle)
×
1404
                conditionsFileName = conditionsFileName[:-1]
×
1405
            # if chunkVariable is not '':
1406
            #
1407
            if legend2 is not None:
×
1408
                fig1.add_artist(legend2)
×
1409
            # fig1.canvas.draw()
1410
            # if legend2 is not None:
1411
            #    ax1.add_artist(legend2)
1412
            #    legend2.set_in_layout(True)
1413
            # if legend1 is not None:
1414
            #    legend1.set_in_layout(True)
1415
            fileName = xAxisVariable + "_" + yAxisVariable + "_" + calculationVariable
×
1416
            for equation in equationDict:
×
1417
                fileName += "_" + equation
×
1418
            fileName += "_" + conditionsFileName
×
1419

1420
            fig1.savefig(os.path.join(pathFolder, fileName + ".png"), bbox_inches="tight")
×
1421

1422
            plt.close()
×
1423

1424
            if self.inputs["setPrintDataForGle"]:
×
1425
                outfile = open(os.path.join(pathFolder, fileName + ".dat"), "w")
×
1426
                outfile.writelines(lines)
×
1427
                outfile.close()
×
1428

1429
    def scatterPlot(self):
×
1430
        pathFolder = self.inputs["pathBase"]
×
1431
        plotVariables = self.inputs["scatterPlot"][0]
×
1432
        differencePlot = False
×
1433
        xVariable = plotVariables[0]
×
1434
        yVariables = [plotVariables[1]]
×
1435
        if "-" in plotVariables[1]:
×
1436
            differencePlot = True
×
1437
            yVariables = plotVariables[1].split("-")
×
1438
        if len(plotVariables) > 2:
×
1439
            seriesVariable = plotVariables[2]
×
1440
        seriesVariable = ""
×
1441

1442
        if self.inputs["typeOfProcess"] == "json":
×
1443
            resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"), recursive=True)
×
1444
        else:
1445
            resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"))
×
1446

1447
        xDict = {}
×
1448
        yDict = {}
×
1449
        diffDict = {}
×
1450

1451
        for file in resultFiles:
×
1452
            with open(file) as f_in:
×
1453
                resultsDict = json.load(f_in)
×
1454
                resultsDict[""] = None
×
1455

1456
            if xVariable not in resultsDict:
×
1457
                continue
×
1458
            for variable in yVariables:
×
1459
                if variable not in resultsDict:
×
1460
                    continue
×
1461

1462
            if str(resultsDict[seriesVariable]) in xDict:
×
1463
                xDict[str(resultsDict[seriesVariable])].append(resultsDict[xVariable])
×
1464
                yDict[str(resultsDict[seriesVariable])].append(resultsDict[yVariables[0]])
×
1465
                if differencePlot:
×
1466
                    diffDict[str(resultsDict[seriesVariable])].append(resultsDict[yVariables[1]])
×
1467
            else:
1468
                xDict[str(resultsDict[seriesVariable])] = [resultsDict[xVariable]]
×
1469
                yDict[str(resultsDict[seriesVariable])] = [resultsDict[yVariables[0]]]
×
1470
                if differencePlot:
×
1471
                    diffDict[str(resultsDict[seriesVariable])] = [resultsDict[yVariables[1]]]
×
1472

1473
        self.doc = latex.LatexReport("", "")
×
1474
        if "latexNames" in self.inputs.keys():
×
1475
            if ":" in self.inputs["latexNames"]:
×
1476
                latexNameFullPath = self.inputs["latexNames"]
×
1477
            else:
1478
                latexNameFullPath = os.path.join(self.configPath, self.inputs["latexNames"])
×
1479
            self.doc.getLatexNamesDict(file=latexNameFullPath)
×
1480
        else:
1481
            self.doc.getLatexNamesDict()
×
1482

1483
        fig1, ax1 = plt.subplots(constrained_layout=True)
×
1484
        colors = plt.rcParams["axes.prop_cycle"].by_key()["color"]
×
1485
        colorsCounter = 0
×
1486

1487
        for entry in xDict:
×
1488
            if differencePlot:
×
1489
                for i in range(len(xDict[entry])):
×
1490
                    ax1.plot(
×
1491
                        [xDict[entry][i], xDict[entry][i]], [diffDict[entry][i], yDict[entry][i]], "-", color="grey"
1492
                    )
1493
                ax1.plot(
×
1494
                    xDict[entry],
1495
                    diffDict[entry],
1496
                    "d",
1497
                    markeredgecolor=colors[colorsCounter],
1498
                    markerfacecolor="w",
1499
                    label=self.doc.getNiceLatexNames(entry) + ", " + self.doc.getNiceLatexNames(yVariables[1]),
1500
                )
1501
                ax1.plot(
×
1502
                    xDict[entry],
1503
                    yDict[entry],
1504
                    "d",
1505
                    color=colors[colorsCounter],
1506
                    label=self.doc.getNiceLatexNames(entry) + ", " + self.doc.getNiceLatexNames(yVariables[0]),
1507
                )
1508
            else:
1509
                ax1.plot(
×
1510
                    xDict[entry],
1511
                    yDict[entry],
1512
                    "d",
1513
                    color=colors[colorsCounter],
1514
                    label=self.doc.getNiceLatexNames(entry),
1515
                )
1516
            colorsCounter += 1
×
1517
            colorsCounter = colorsCounter % len(colors)
×
1518
        if seriesVariable != "":
×
1519
            ax1.legend(loc="best")
×
1520
        ax1.set_xlabel(self.doc.getNiceLatexNames(xVariable))
×
1521
        if differencePlot:
×
1522
            ax1.set_ylabel(
×
1523
                self.doc.getNiceLatexNames(yVariables[0]) + " / " + self.doc.getNiceLatexNames(yVariables[1])
1524
            )
1525
        else:
1526
            ax1.set_ylabel(self.doc.getNiceLatexNames(yVariables[0]))
×
1527

1528
        fileName = "scatter_*" + xVariable
×
1529
        for name in yVariables:
×
1530
            fileName += "_" + name
×
1531
        fileName += "_" + seriesVariable
×
1532
        fileName = re.sub(r"[^\w\-_\. ]", "", fileName)
×
1533

1534
        line = seriesVariable + "\t" + xVariable
×
1535
        for name in yVariables:
×
1536
            line += "\t" + name
×
1537
        lines = line + "\n"
×
1538
        for key in xDict:
×
1539
            for i in range(len(xDict[key])):
×
1540
                line = key + "\t" + str(xDict[key][i]) + "\t" + str(yDict[key][i])
×
1541
                if differencePlot:
×
1542
                    line += "\t" + str(diffDict[key][i])
×
1543
                lines += line + "\n"
×
1544

1545
        outfile = open(os.path.join(pathFolder, fileName + ".dat"), "w")
×
1546
        outfile.writelines(lines)
×
1547
        outfile.close()
×
1548

1549
        fig1.savefig(os.path.join(pathFolder, fileName + ".png"), bbox_inches="tight")
×
1550
        plt.close()
×
1551

1552
    def transferPathInfoToJson(self):
×
1553
        parDict = {}
×
1554
        for parList in self.inputs["pathInfoToJson"]:
×
1555
            parDict[parList[0]] = parList[1:]
×
1556

1557
        pathFolder = self.inputs["pathBase"]
×
1558
        resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"), recursive=True)
×
1559

1560
        for file in resultFiles:
×
1561
            with open(file) as f_in:
×
1562
                resultsDict = json.load(f_in)
×
1563

1564
            for parName in parDict:
×
1565
                keyNotFound = True
×
1566
                for key in parDict[parName]:
×
1567
                    if key in file:
×
1568
                        resultsDict[parName] = key
×
1569
                        keyNotFound = False
×
1570
                if keyNotFound:
×
1571
                    resultsDict[parName] = ""
×
1572

1573
            self.logger.info("Adding path info to " + os.path.split(file)[-1])
×
1574

1575
            with open(file, "w") as f_out:
×
1576
                json.dump(resultsDict, f_out, indent=2, separators=(",", ": "))
×
1577

1578
    def calculateInJson(self):
×
1579
        pathFolder = self.inputs["pathBase"]
×
1580
        resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"), recursive=True)
×
1581

1582
        for file in resultFiles:
×
1583
            with open(file) as f_in:
×
1584
                resultsDict = json.load(f_in)
×
1585

1586
            for equation in self.inputs["jsonCalc"][0]:
×
1587
                if "=" not in equation:
×
1588
                    self.logger.error("Invalid equation statement in `jsonCalc`")
×
1589
                    return -1
×
1590
                else:
1591
                    for variable in re.split(r"\W", equation):
×
1592
                        if variable != "" and variable != "round" and not (self.isStringNumber(variable)):
×
1593
                            equation = equation.replace(variable, 'resultsDict["%s"]' % variable)
×
1594
                    exec(equation)
×
1595

1596
            self.logger.info("Adding equation result to " + os.path.split(file)[-1])
×
1597

1598
            with open(file, "w") as f_out:
×
1599
                json.dump(resultsDict, f_out, indent=2, separators=(",", ": "))
×
1600

1601
    def insertIntoJson(self):
×
1602
        pathFolder = self.inputs["pathBase"]
×
1603
        resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"), recursive=True)
×
1604

1605
        for file in resultFiles:
×
1606
            with open(file) as f_in:
×
1607
                resultsDict = json.load(f_in)
×
1608

1609
            for item in self.inputs["jsonInsert"]:
×
1610
                resultsDict[item[0]] = item[1]
×
1611

1612
            self.logger.info("Inserting additional items to " + os.path.split(file)[-1])
×
1613

1614
            with open(file, "w") as f_out:
×
1615
                json.dump(resultsDict, f_out, indent=2, separators=(",", ": "))
×
1616

1617
    def printBoxPlotGLEData(self):
×
1618
        pathFolder = self.inputs["pathBase"]
×
1619
        for SPFload in self.inputs["printBoxPlotGLEData"]:
×
1620
            SPF = SPFload[0]
×
1621

1622
            # SPF = plotVariables[0]
1623
            # SPFload = []
1624
            SPFValues = []
×
1625

1626
            for file in glob.glob(os.path.join(pathFolder, "**/*-results.json")):
×
1627
                with open(file) as f_in:
×
1628
                    resultsDict = json.load(f_in)
×
1629
                    # resultsDict[''] = None
1630
                    # name, index = str(SPF).split('[')
1631
                    # index = int(index.replace(']', ''))
1632

1633
                    SPFValue = resultsDict[SPF]
×
1634
                    SPFValues.append(SPFValue)
×
1635

1636
        SPFV = num.array(SPFValues)
×
1637

1638
        SPFQ25 = num.quantile(SPFV, 0.25)
×
1639
        SPFQ50 = num.quantile(SPFV, 0.5)
×
1640
        SPFQ75 = num.quantile(SPFV, 0.75)
×
1641
        SPFAv = num.average(SPFV)
×
1642
        SPFMin = num.min(SPFV)
×
1643
        SPFMax = num.max(SPFV)
×
1644

1645
        # line = "\n";
1646
        # lines = lines + line
1647

1648
        lines = "%8.4f\t%8.4f\t%8.4f\t%8.4f\t%8.4f\t%8.4f\t" % (SPFAv, SPFMin, SPFQ25, SPFQ50, SPFQ75, SPFMax)
×
1649
        outfileName = "yearSpfShpDisgle"
×
1650

1651
        outfile = open(os.path.join(pathFolder, outfileName + ".dat"), "w")
×
1652
        outfile.writelines(lines)
×
1653
        outfile.close()
×
1654

1655
    def plotMonthlyBarComparison(self):
×
1656
        pathFolder = self.inputs["pathBase"]
×
1657
        for plotVariables in self.inputs["compareMonthlyBarsPlot"]:
×
1658
            seriesVariable = plotVariables[1]
×
1659
            valueVariable = plotVariables[0]
×
1660
            legend = []
×
1661
            inVar = []
×
1662
            for file in glob.glob(os.path.join(pathFolder, "**/*-results.json")):
×
1663
                with open(file) as f_in:
×
1664
                    resultsDict = json.load(f_in)
×
1665
                    resultsDict[""] = None
×
1666
                legend.append(resultsDict[seriesVariable])
×
1667
                inVar.append(num.array(resultsDict[valueVariable]))
×
1668
            nameFile = "_".join(plotVariables)
×
1669
            titlePlot = "Balance"
×
1670
            self.plot = plot.PlotMatplotlib(language="en")
×
1671
            self.plot.setPath(pathFolder)
×
1672
            self.myShortMonths = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
×
1673
            self.doc = latex.LatexReport("", "")
×
1674
            if "latexNames" in self.inputs.keys():
×
1675
                if ":" in self.inputs["latexNames"]:
×
1676
                    latexNameFullPath = self.inputs["latexNames"]
×
1677
                else:
1678
                    latexNameFullPath = os.path.join(self.configPath, self.inputs["latexNames"])
×
1679
                self.doc.getLatexNamesDict(file=latexNameFullPath)
×
1680
            else:
1681
                self.doc.getLatexNamesDict()
×
1682
            if "matplotlibStyle" in self.inputs.keys():
×
1683
                stylesheet = self.inputs["matplotlibStyle"]
×
1684
            else:
1685
                stylesheet = "word.mplstyle"
×
1686
            if stylesheet in plt.style.available:
×
1687
                self.stylesheet = stylesheet
×
1688
            else:
1689
                root = os.path.dirname(os.path.abspath(__file__))
×
1690
                self.stylesheet = os.path.join(root, r"..\\plot\\stylesheets", stylesheet)
×
1691
            plt.style.use(self.stylesheet)
×
1692
            niceLegend = []
×
1693
            for entry in legend:
×
1694
                niceLegend.append(self.doc.getNiceLatexNames(entry))
×
1695
            namePdf = self.plot.plotMonthlyNBar(
×
1696
                inVar,
1697
                niceLegend,
1698
                self.doc.getNiceLatexNames(valueVariable),
1699
                nameFile,
1700
                10,
1701
                self.myShortMonths,
1702
                useYear=True,
1703
            )
1704

1705
    def plotComparisonSeaborn(self):
×
1706
        pathFolder = self.inputs["pathBase"]
×
1707
        plotVariables = self.inputs["comparePlot"]
×
1708
        if len(plotVariables) < 2:
×
1709
            raise ValueError(
×
1710
                "You did not specify variable names and labels for the x and the y Axis in a compare Plot line"
1711
            )
1712
        elif len(plotVariables) == 2:
×
1713
            plotVariables.extend([None, None])
×
1714
        elif len(plotVariables) == 3:
×
1715
            plotVariables.append([None])
×
1716

1717
        df = pd.DataFrame(columns=plotVariables)
×
1718
        for file in glob.glob(os.path.join(pathFolder, "**/*-results.json")):
×
1719
            with open(file) as f_in:
×
1720
                resultsDict = json.load(f_in)
×
1721
            plotDict = {k: [float("{:.2f}".format(resultsDict[k]))] for k in plotVariables}
×
1722
            df = df.append(pd.DataFrame.from_dict(plotDict))
×
1723
        snsPlot = sns.lineplot(
×
1724
            x=plotVariables[0],
1725
            y=plotVariables[1],
1726
            hue=plotVariables[2],
1727
            style=plotVariables[3],
1728
            palette=None,
1729
            markers=True,
1730
            data=df,
1731
        )
1732
        fig = snsPlot.get_figure()
×
1733
        name = "_".join(plotVariables)
×
1734
        fig.savefig(os.path.join(pathFolder, name + ".png"), dpi=500)
×
1735

1736
    def changeFile(self, source, end):
×
1737
        # todo: this function is currently not working
1738

1739
        found = False
×
1740
        for i in range(len(self.lines)):
×
1741
            # self.lines[i].replace(source,end)
1742
            if self.lines[i] == source:
×
1743
                self.lines[i] = end
×
1744
                found = True
×
1745

1746
        if found == False:
×
1747
            self.logger.warning("changeFile was not able to change %s by %s" % (source, end))
×
1748

1749
    def calcCost(self, fileNamesToRead=None):
×
1750
        resultsDirPath = _pl.Path(self.inputs["pathBase"])
×
1751
        configFilePath = _pl.Path(self.inputs["cost"])
×
1752
        shallWriteReport = self.inputs["costPdf"]
×
1753
        processType = _cc.OTHER if not fileNamesToRead else _cc.CasesDefined(fileNamesToRead)
×
1754
        _cc.calculateCostsAndWriteReports(configFilePath, resultsDirPath, shallWriteReport, processType)
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc