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

SPF-OST / pytrnsys / 11666188880

04 Nov 2024 02:25PM UTC coverage: 26.098% (-0.1%) from 26.233%
11666188880

push

github

web-flow
Merge pull request #217 from SPF-OST/integrate-collect-jsons

Add `collectJsonsIntoCsv` command to processing

0 of 72 new or added lines in 2 files covered. (0.0%)

2 existing lines in 1 file now uncovered.

3589 of 13752 relevant lines covered (26.1%)

0.26 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
×
NEW
14
import collections.abc as _cabc
×
15

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

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

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

40

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

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

59
        return f"Finished: {self.fileName}"
×
60

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

86
            fileEndingsDefault = ["-results.json", "-report.pdf", "-plots.html"]
×
87

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

101

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

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

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

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

162
        self.individualFile = False
×
163

164
    def setFilteredFolders(self, foldersNotUsed):
×
165
        self.filteredfolder = foldersNotUsed
×
166

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

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

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

186
        Parameters
187
        ---------
188
        sample : str
189
            String to be checked
190

191
        Returns
192
        -------
193
        bool
194
            Indicates whether sample consists only of a number
195

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

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

207
        returnDict = {}
×
208

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

223
    def process(self):
×
224
        processingCases = []
×
225
        fileName = []
×
226

227
        self.filesReturn = None
×
228

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

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

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

242
                self.filesReturn = files
×
243

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

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

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

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

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

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

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

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

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

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

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

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

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

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

332
                        else:
333
                            processTrnsysDf = self._createProcessTrnsysDf(pathFolder, name)
×
334

335
                            self.logger.info("%s will be processed" % name)
×
336

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

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

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

349
            stringArray cities
350
            stringArray fileTypes
351

352
            examples for cities:
353

354
            "GVE" "BER" "BAS" "SMA" "DAV" "OTL"
355

356
            examples for fileTypes:
357

358
            "sia" "hourly" "monthlyMean"
359
            """
360

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

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

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

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

384
                                else:
385
                                    processTrnsysDf = self._createProcessTrnsysDf(pathFolder, name)
×
386

387
                                    self.logger.info("%s will be processed" % name)
×
388

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

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

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

413
            pool = mp.Pool(processes=maxNumberOfCPU)
×
414

415
            results = pool.map(_ProcessingCase.run, processingCases)
×
416

417
            pool.close()
×
418
            pool.join()
×
419

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

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

429
            self.calcCost(fileNameList)
×
430

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

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

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

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

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

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

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

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

464
        if "scatterPlot" in self.inputs.keys():
×
465
            self.scatterPlot()
×
466

467
        if "jsonCalc" in self.inputs.keys():
×
468
            self.calculateInJson()
×
469

470
        if "jsonInsert" in self.inputs.keys():
×
471
            self.insertIntoJson()
×
472

473
        if "calcClimateCorrections" in self.inputs.keys():
×
474
            self.calculateClimateCorrections()
×
475

476
        if "compareMonthlyBarsPlot" in self.inputs.keys():
×
477
            self.plotMonthlyBarComparison()
×
478

479
        if "printBoxPlotGLEData" in self.inputs.keys():
×
480
            self.printBoxPlotGLEData()
×
481

NEW
482
        if "collectJsonsIntoCsv" in self.inputs.keys():
×
NEW
483
            commands = self.inputs["collectJsonsIntoCsv"]
×
NEW
484
            self.collectJsonsIntoCsv(commands)
×
485

UNCOV
486
        return self.filesReturn  # Dc maybe not the best way
×
487

488
    def _addCasesForYears(
×
489
        self,
490
        processTrnsysDf: processTrnsys.ProcessTrnsysDf,
491
        pathFolder: str,
492
        name: str,
493
        processingCases: list[_ProcessingCase],
494
    ) -> None:
495
        yearReadInMonthlyFileBase = self.inputs["yearReadedInMonthlyFile"]
×
496
        if yearReadInMonthlyFileBase == -1:
×
497
            yearReadInMonthlyFileBase = 0
×
498

499
        for i in range(self.inputs["numberOfYearsInHourlyFile"]):
×
500
            yearReadInMonthlyFile = yearReadInMonthlyFileBase + i
×
501
            processingCase = self._createProcessingCase(
×
502
                processTrnsysDf,
503
                pathFolder,
504
                name,
505
                yearReadInMonthlyFile=yearReadInMonthlyFile,
506
            )
507
            processingCases.append(processingCase)
×
508

509
    def _createProcessingCase(
×
510
        self,
511
        processTrnsyDf: processTrnsys.ProcessTrnsysDf,
512
        locationPath: str,
513
        fileName: str,
514
        individualFiles: _tp.Optional[_tp.Sequence[str]] = None,
515
        yearReadInMonthlyFile: int = -1,
516
    ) -> _ProcessingCase:
517
        return _ProcessingCase(
×
518
            self.logger, processTrnsyDf, locationPath, fileName, self.inputs, individualFiles, yearReadInMonthlyFile
519
        )
520

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

532
            conditionDict = {}
×
533
            equationDict = {}
×
534
            calcVariableDict = {}
×
535
            for plotVariable in plotVariables:
×
536
                if ":" in plotVariable:
×
537
                    conditionEntry, conditionValue = plotVariable.split(":")
×
538
                    conditionDict[conditionEntry] = conditionValue
×
539
                elif "=" in plotVariable:
×
540
                    equationVariable, equationExpression = plotVariable.split("=")
×
541
                    equationDict[equationVariable] = equationExpression
×
542
                    for variable in re.split(r"\W", equationExpression):
×
543
                        if variable != "" and not (self.isStringNumber(variable)):
×
544
                            calcVariableDict[variable] = ""
×
545

546
            plotXDict = {}
×
547
            plotYDict = {}
×
548

549
            if self.inputs["typeOfProcess"] == "json":
×
550
                resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"), recursive=True)
×
551
            else:
552
                resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"))
×
553

554
            xVariable = []
×
555

556
            for file in resultFiles:
×
557
                with open(file) as f_in:
×
558
                    resultsDict = json.load(f_in)
×
559
                    resultsDict[""] = None
×
560

561
                conditionList = []
×
562
                for conditionEntry in conditionDict:
×
563
                    entryClass = type(resultsDict[conditionEntry])
×
564
                    conditionDict[conditionEntry] = entryClass(conditionDict[conditionEntry])
×
565
                    conditionList.append(conditionDict[conditionEntry] == resultsDict[conditionEntry])
×
566

567
                if all(conditionList):
×
568
                    if "[" not in xAxisVariable:
×
569
                        xAxis = resultsDict[xAxisVariable]
×
570
                    else:
571
                        name, index = str(xAxisVariable).split("[")
×
572
                        index = int(index.replace("]", ""))
×
573
                        xAxis = resultsDict[name][index]
×
574
                    if "[" not in yAxisVariable:
×
575
                        yAxis = resultsDict[yAxisVariable]
×
576
                    else:
577
                        name, index = str(yAxisVariable).split("[")
×
578
                        index = int(index.replace("]", ""))
×
579
                        yAxis = resultsDict[name][index]
×
580

581
                    xVariable.append(xAxis)
×
582

583
                    chunkVariable = ""
×
584

585
                    if resultsDict[chunkVariable] not in plotXDict.keys():
×
586
                        plotXDict[resultsDict[chunkVariable]] = {}
×
587
                        plotYDict[resultsDict[chunkVariable]] = {}
×
588
                        plotXDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]] = [xAxis]
×
589
                        plotYDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]] = [yAxis]
×
590
                    elif resultsDict[calculationVariable] not in plotXDict[resultsDict[chunkVariable]].keys():
×
591
                        plotXDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]] = [xAxis]
×
592
                        plotYDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]] = [yAxis]
×
593
                    else:
594
                        plotXDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]].append(xAxis)
×
595
                        plotYDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]].append(yAxis)
×
596

597
                else:
598
                    pass
×
599

600
            for variable in calcVariableDict:
×
601
                calcVariableDict[variable] = num.array(plotYDict[None][variable])
×
602

603
            calcVariableDict["equationDict"] = equationDict
×
604
            for equation in equationDict:
×
605
                calcVariableDict["equation"] = equation
×
606
                exec("equationDict[equation]=" + equationDict[equation], calcVariableDict)
×
607

608
            xVariable = list(dict.fromkeys(xVariable))
×
609

610
            dataFrameDict = {}
×
611
            dataFrameDict[xAxisVariable] = xVariable
×
612
            dataFrameDict.update(equationDict)
×
613

614
            saveDf = pd.DataFrame(data=dataFrameDict)
×
615

616
            conditionsFileName = ""
×
617
            for conditionEntry in conditionDict:
×
618
                conditionsFileName += "_" + conditionEntry + "=" + str(conditionDict[conditionEntry])
×
619

620
            fileName = xAxisVariable + "_" + yAxisVariable + "_" + calculationVariable
×
621
            for equation in equationDict:
×
622
                fileName += "_" + equation
×
623
            fileName += conditionsFileName
×
624

625
            fullCsvPath = os.path.join(pathFolder, fileName + ".csv")
×
626
            saveDf.to_csv(fullCsvPath, index=False, sep=";")
×
627

628
    def plotComparison(self, commands, shallPlotUncertainties: bool):
×
629
        pathFolder = self.inputs["pathBase"]
×
630
        typeOfProcess = self.inputs["typeOfProcess"]
×
631
        logger = self.logger
×
632
        latexNames = self.inputs.get("latexNames")
×
633
        configPath = self.configPath
×
634
        stylesheet = self.inputs.get("matplotlibStyle")
×
635
        plotStyle = self.inputs["plotStyle"]
×
636
        comparePlotUserName = self.inputs["comparePlotUserName"]
×
637
        setPrintDataForGle = self.inputs["setPrintDataForGle"]
×
638
        extensionFig = self.inputs["extensionFig"]
×
639

640
        for plotVariables in commands:
×
641
            _pc.createPlot(
×
642
                plotVariables,
643
                pathFolder,
644
                logger,
645
                imageFileExtension=extensionFig,
646
                typeOfProcess=typeOfProcess,
647
                relativeLatexNamesFilePath=latexNames,
648
                configPath=configPath,
649
                stylesheetNameOrPath=stylesheet,
650
                plotStyle=plotStyle,
651
                comparePlotUserName=comparePlotUserName,
652
                shallPrintDataForGle=setPrintDataForGle,
653
                shallPlotUncertainties=shallPlotUncertainties,
654
            )
655

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

673
            conditionDict = {}
×
674
            for plotVariable in plotVariables:
×
675
                if ":" in plotVariable:
×
676
                    conditionEntry, conditionValue = plotVariable.split(":")
×
677
                    conditionDict[conditionEntry] = conditionValue
×
678

679
            plotXDict = {}
×
680
            plotYDict = {}
×
681

682
            seriesColors = {}
×
683
            colorsCounter = 0
×
684
            colors = plt.rcParams["axes.prop_cycle"].by_key()["color"]
×
685

686
            if self.inputs["typeOfProcess"] == "json":
×
687
                resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"), recursive=True)
×
688
            else:
689
                resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"))
×
690

691
            conditionNeverMet = True
×
692

693
            for file in resultFiles:
×
694
                with open(file) as f_in:
×
695
                    resultsDict = json.load(f_in)
×
696
                    resultsDict[""] = None
×
697

698
                conditionList = []
×
699
                for conditionEntry in conditionDict:
×
700
                    entryClass = type(resultsDict[conditionEntry])
×
701
                    conditionDict[conditionEntry] = entryClass(conditionDict[conditionEntry])
×
702
                    conditionList.append(conditionDict[conditionEntry] == resultsDict[conditionEntry])
×
703

704
                if all(conditionList):
×
705
                    conditionNeverMet = False
×
706

707
                    if resultsDict[seriesVariable] not in seriesColors.keys():
×
708
                        seriesColors[resultsDict[seriesVariable]] = colors[colorsCounter]
×
709
                        colorsCounter += 1
×
710

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

735
                else:
736
                    pass
×
737

738
            if conditionNeverMet:
×
739
                self.logger.warning(
×
740
                    'The following conditions from "comparePlotConditional" were never met all at once:'
741
                )
742
                for entry in conditionDict:
×
743
                    self.logger.warning("%s = %s" % (entry, str(conditionDict[entry])))
×
744
                self.logger.warning("The respective plot cannot be generated")
×
745
                return
×
746

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

767
            fig1, ax1 = plt.subplots(constrained_layout=True, figsize=[8, 3], dpi=200)
×
768
            if self.inputs["plotStyle"] == "line":
×
769
                styles = ["x-", "x--", "x-.", "x:", "o-", "o--", "o-.", "o:"]
×
770
            elif self.inputs["plotStyle"] == "dot":
×
771
                styles = ["x", "o", "+", "d", "s", "v", "^", "h"]
×
772
            else:
773
                print("Invalid 'plotStyle' argument")
×
774

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

788
                YBarPlot = []
×
789
                labelBarPlot = []
×
790
                keyBarPlot = []
×
791
                for key in plotXDict[chunk].keys():
×
792
                    index = num.argsort(plotXDict[chunk][key])
×
793
                    myX = num.array(plotXDict[chunk][key])[index]
×
794
                    myY = num.array(plotYDict[chunk][key])[index]
×
795

796
                    YBarPlot.append(myY)
×
797
                    mySize = len(myX)
×
798
                    XBase = num.arange(len(myX))
×
799
                    keyBarPlot.append(key)
×
800

801
                    if key is not None and not isinstance(key, str):
×
802
                        labelValue = round(float(key), 2)
×
803
                    elif key is not None:
×
804
                        labelValue = key
×
805
                    if key is not None and labelValue not in labelSet:
×
806
                        if not isinstance(labelValue, str):
×
807
                            label = "{0:.1f}".format(labelValue)
×
808
                            labelBarPlot.append(label)
×
809
                        else:
810
                            label = labelValue
×
811
                            label = self.doc.getNiceLatexNames(label)
×
812
                            labelBarPlot.append(label)
×
813

814
                    labelSet.add(labelValue)
×
815

816
                N = len(keyBarPlot)
×
817
                Number = num.arange(N)
×
818

819
                widthBarPlot = 1 / (N + 1)
×
820

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

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

849
                    line = "\n"
850
                    lines = lines + line
851
            else:
852
                for i in range(mySize):
×
853
                    for chunk, style in zip(plotXDict.keys(), styles):
×
854
                        for key in plotXDict[chunk].keys():  # the varables that appear in the legend
×
855
                            index = num.argsort(plotXDict[chunk][key])
×
856
                            myX = num.array(plotXDict[chunk][key])[index]
×
857
                            myY = num.array(plotYDict[chunk][key])[index]
×
858

859
                            if len(myX) < i - 1:
×
860
                                if type(myX[i]) == num.str_ and type(myY[i]) == num.str_:
×
861
                                    line = myX[i] + "\t" + myY[i] + "\t"
×
862
                                elif type(myX[i]) == num.str_:
×
863
                                    line = myX[i] + "\t" + "%8.4f\t" % myY[i]
×
864
                                elif type(myY[i]) == num.str_:
×
865
                                    line = "%8.4f\t" % myX[i] + myX[i] + "\t"
×
866
                                else:
867
                                    line = "%8.4f\t%8.4f\t" % (myX[i], myY[i])
×
868
                                lines = lines + line
×
869

870
                    line = "\n"
×
871
                    lines = lines + line
×
872

873
            # box = ax1.get_position()
874
            # ax1.set_position([box.x0, box.y0, box.width, box.height])
875

876
            if chunkVariable != "":
×
877
                legend2 = fig1.legend(
×
878
                    [dummy_line[0] for dummy_line in dummy_lines],
879
                    chunkLabels,
880
                    title=self.doc.getNiceLatexNames(chunkVariable),
881
                    bbox_to_anchor=(1.5, 1.0),
882
                    bbox_transform=ax1.transAxes,
883
                )
884

885
            else:
886
                legend2 = None
×
887
            if seriesVariable != "":
×
888
                legend1 = fig1.legend(
×
889
                    title=self.doc.getNiceLatexNames(seriesVariable),
890
                    bbox_to_anchor=(1.15, 1.0),
891
                    bbox_transform=ax1.transAxes,
892
                )
893

894
            else:
895
                legend1 = None
×
896
            ax1.set_xlabel(self.doc.getNiceLatexNames(xAxisVariable))
×
897
            ax1.set_ylabel(self.doc.getNiceLatexNames(yAxisVariable))
×
898
            ax1.set_xticks(XBase)
×
899
            ax1.set_xticklabels(myX)
×
900

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

903
            width2 = 0.33
×
904
            ax2.bar(
×
905
                XBase - 0.165,
906
                (YBarPlot[0] - YBarPlot[2]) / YBarPlot[2] * 100,
907
                color=colors[0],
908
                edgecolor="black",
909
                width=width2,
910
                label=labelBarPlot[0],
911
            )
912
            ax2.bar(
×
913
                XBase + 0.165,
914
                (YBarPlot[1] - YBarPlot[2]) / YBarPlot[2] * 100,
915
                color=colors[1],
916
                edgecolor="black",
917
                width=width2,
918
                label=labelBarPlot[1],
919
            )
920

921
            if chunkVariable != "":
×
922
                legend2 = fig2.legend(
×
923
                    [dummy_line[0] for dummy_line in dummy_lines],
924
                    chunkLabels,
925
                    title=self.doc.getNiceLatexNames(chunkVariable),
926
                    bbox_to_anchor=(1.5, 1.0),
927
                    bbox_transform=ax2.transAxes,
928
                )
929

930
            else:
931
                legend2 = None
×
932
            if seriesVariable != "":
×
933
                legend1 = fig2.legend(
×
934
                    title=self.doc.getNiceLatexNames(seriesVariable),
935
                    bbox_to_anchor=(1.15, 1.0),
936
                    bbox_transform=ax2.transAxes,
937
                )
938

939
            else:
940
                legend1 = None
×
941

942
            ax2.set_xlabel(self.doc.getNiceLatexNames(xAxisVariable))
×
943
            ax2.set_ylabel(self.doc.getNiceLatexNames(yAxisVariable) + "[%]")
×
944
            ax2.set_xticks(XBase)
×
945
            ax2.set_xticklabels(myX)
×
946

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

988
            fig2.savefig(os.path.join(pathFolder, "diffPlot" + fileName + ".png"), bbox_inches="tight")
×
989
            plt.close()
×
990

991
            if self.inputs["setPrintDataForGle"]:
×
992
                outfile = open(os.path.join(pathFolder, fileName + ".dat"), "w")
×
993
                outfile.writelines(lines)
×
994
                outfile.close()
×
995

996
    def _plotViolin(self):
×
997
        allPlotVariables = self.inputs["violinPlot"]
×
998
        for plotVariables in allPlotVariables:
×
999
            self._plotBoxOrViolin(plotVariables, shallPlotViolin=True)
×
1000

1001
    def _plotBox(self):
×
1002
        allPlotVariables = self.inputs.get("boxPlot", []) + self.inputs.get("boxPlotConditional", [])
×
1003
        for plotVariables in allPlotVariables:
×
1004
            self._plotBoxOrViolin(plotVariables, shallPlotViolin=False)
×
1005

1006
    def _plotBoxOrViolin(self, plotVariables, shallPlotViolin):
×
1007
        pathFolder = self.inputs["pathBase"]
×
1008
        extensionFig = self.inputs["extensionFig"]
×
1009

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

1013
        yAxisVariable = plotVariables[0]
×
1014
        chunkVariable = ""
×
1015
        seriesVariable = ""
×
1016
        serializedConditions = plotVariables[1:]
×
1017
        if len(plotVariables) >= 2 and not _conds.mayBeSerializedCondition(plotVariables[1]):
×
1018
            seriesVariable = plotVariables[1]
×
1019
            serializedConditions = plotVariables[2:]
×
1020
        if len(plotVariables) >= 3 and not _conds.mayBeSerializedCondition(plotVariables[2]):
×
1021
            chunkVariable = plotVariables[2]
×
1022
            serializedConditions = plotVariables[3:]
×
1023

1024
        conditions = _conds.createConditions(serializedConditions)
×
1025

1026
        plotYDict = {}
×
1027

1028
        seriesColors = {}
×
1029
        colorsCounter = 0
×
1030
        colors = plt.rcParams["axes.prop_cycle"].by_key()["color"]
×
1031

1032
        if self.inputs["typeOfProcess"] == "json":
×
1033
            resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"), recursive=True)
×
1034
        else:
1035
            resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"))
×
1036

1037
        conditionNeverMet = True
×
1038

1039
        for file in resultFiles:
×
1040
            with open(file) as f_in:
×
1041
                resultsDict = json.load(f_in)
×
1042
                resultsDict[""] = None
×
1043

1044
            conditionsFulfilled = conditions.doResultsSatisfyConditions(resultsDict)
×
1045

1046
            if conditionsFulfilled:
×
1047
                conditionNeverMet = False
×
1048

1049
                if resultsDict[seriesVariable] not in seriesColors.keys():
×
1050
                    seriesColors[resultsDict[seriesVariable]] = colors[colorsCounter]
×
1051
                    colorsCounter += 1
×
1052
                    colorsCounter = colorsCounter % len(colors)
×
1053

1054
                if "[" not in yAxisVariable:
×
1055
                    yAxis = resultsDict[yAxisVariable]
×
1056
                else:
1057
                    name, index = str(yAxisVariable).split("[")
×
1058
                    index = int(index.replace("]", ""))
×
1059
                    yAxis = resultsDict[name][index]
×
1060

1061
                if isinstance(yAxis, dict):
×
1062
                    uncertainFloat: _uf.UncertainFloat = _uf.UncertainFloat.from_dict(yAxis)
×
1063
                    yAxis = uncertainFloat.mean
×
1064

1065
                if resultsDict[chunkVariable] not in plotYDict.keys():
×
1066
                    plotYDict[resultsDict[chunkVariable]] = {}
×
1067
                    plotYDict[resultsDict[chunkVariable]][resultsDict[seriesVariable]] = [yAxis]
×
1068
                elif resultsDict[seriesVariable] not in plotYDict[resultsDict[chunkVariable]].keys():
×
1069
                    plotYDict[resultsDict[chunkVariable]][resultsDict[seriesVariable]] = [yAxis]
×
1070
                else:
1071
                    plotYDict[resultsDict[chunkVariable]][resultsDict[seriesVariable]].append(yAxis)
×
1072

1073
            else:
1074
                pass
×
1075

1076
        if conditionNeverMet:
×
1077
            self.logger.warning('The following conditions from "plotBoxConditional" were never met all at once:')
×
1078
            for condition in conditions.conditions:
×
1079
                self.logger.warning(condition)
×
1080
            self.logger.warning("The respective plot cannot be generated")
×
1081
            return
×
1082

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

1103
        fig1, ax1 = plt.subplots(constrained_layout=True)
×
1104
        if self.inputs["plotStyle"] == "line":
×
1105
            styles = ["x-", "x--", "x-.", "x:", "o-", "o--", "o-.", "o:"]
×
1106
        elif self.inputs["plotStyle"] == "dot":
×
1107
            styles = ["x", "o", "+", "d", "s", "v", "^", "h"]
×
1108
        else:
1109
            print("Invalid 'plotStyle' argument")
×
1110

1111
        dummy_lines = []
×
1112
        chunkLabels = []
×
1113

1114
        myY = []
×
1115
        for chunk, style in zip(plotYDict.keys(), styles):
×
1116
            dummy_lines.append(ax1.plot([], [], style, c="black"))
×
1117
            if chunk is not None:
×
1118
                if not isinstance(chunk, str):
×
1119
                    chunkLabel = round(float(chunk), 2)
×
1120
                    chunkLabels.append("{:.2f}".format(chunkLabel))
×
1121
                else:
1122
                    chunkLabels.append(chunk)
×
1123

1124
            for key in plotYDict[chunk].keys():
×
1125
                sortedSeriesYs = num.sort(plotYDict[chunk][key])
×
1126

1127
                myY.append(sortedSeriesYs)
×
1128

1129
        cityName = []
×
1130
        for chunk, style in zip(plotYDict.keys(), styles):
×
1131
            for key in plotYDict[chunk].keys():
×
1132
                if type(key) == str:
×
1133
                    keyNice = self.doc.getNiceLatexNames(key)
×
1134
                    cityName.append(keyNice)
×
1135
                else:
1136
                    cityName.append(key)
×
1137

1138
        if shallPlotViolin:
×
1139
            _seb.violinplot(data=myY, split=True, scale="area", inner="quartile", ax=ax1)
×
1140
        else:
1141
            ax1.boxplot(myY, showfliers=False)
×
1142

1143
        ax1.set_xticklabels(cityName)
×
1144

1145
        ax1.set_ylabel(self.doc.getNiceLatexNames(yAxisVariable))
×
1146

1147
        conditionsFileName = ""
×
1148
        conditionsTitle = ""
×
1149
        for condition in conditions.conditions:
×
1150
            conditionsFileName += condition.serializedCondition
×
1151
            if conditionsTitle != "":
×
1152
                conditionsTitle += ", " + condition.serializedCondition
×
1153
            else:
1154
                conditionsTitle += condition.serializedCondition
×
1155

1156
        conditionsTitle = conditionsTitle.replace("RANGE", "")
×
1157
        conditionsTitle = conditionsTitle.replace("LIST", "")
×
1158

1159
        conditionsFileName = conditionsFileName.replace("==", "=")
×
1160
        conditionsFileName = conditionsFileName.replace(">", "_g_")
×
1161
        conditionsFileName = conditionsFileName.replace("<", "_l_")
×
1162
        conditionsFileName = conditionsFileName.replace(">=", "_ge_")
×
1163
        conditionsFileName = conditionsFileName.replace("<=", "_le_")
×
1164
        conditionsFileName = conditionsFileName.replace("|", "_o_")
×
1165
        conditionsFileName = conditionsFileName.replace("RANGE:", "")
×
1166
        conditionsFileName = conditionsFileName.replace("LIST:", "")
×
1167

1168
        ax1.set_title(conditionsTitle)
×
1169

1170
        possibleFileNameComponents = [yAxisVariable, seriesVariable, chunkVariable, conditionsFileName]
×
1171
        fileNameComponents = [c for c in possibleFileNameComponents if c]
×
1172
        fileName = "_".join(fileNameComponents)
×
1173

1174
        fileNamePrefix = "ViolinPlot" if shallPlotViolin else "BoxPlot"
×
1175

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

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

1190
            conditionDict = {}
×
1191
            equationDict = {}
×
1192
            calcVariableDict = {}
×
1193
            for plotVariable in plotVariables:
×
1194
                if ":" in plotVariable:
×
1195
                    conditionEntry, conditionValue = plotVariable.split(":")
×
1196
                    conditionDict[conditionEntry] = conditionValue
×
1197
                elif "=" in plotVariable:
×
1198
                    equationVariable, equationExpression = plotVariable.split("=")
×
1199
                    equationDict[equationVariable] = equationExpression
×
1200
                    for variable in re.split(r"\W", equationExpression):
×
1201
                        if variable != "" and not (self.isStringNumber(variable)):
×
1202
                            calcVariableDict[variable] = ""
×
1203

1204
            plotXDict = {}
×
1205
            plotYDict = {}
×
1206

1207
            seriesColors = {}
×
1208
            colorsCounter = 0
×
1209
            colors = plt.rcParams["axes.prop_cycle"].by_key()["color"]
×
1210

1211
            if self.inputs["typeOfProcess"] == "json":
×
1212
                resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"), recursive=True)
×
1213
            else:
1214
                resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"))
×
1215

1216
            for file in resultFiles:
×
1217
                with open(file) as f_in:
×
1218
                    resultsDict = json.load(f_in)
×
1219
                    resultsDict[""] = None
×
1220

1221
                conditionList = []
×
1222
                for conditionEntry in conditionDict:
×
1223
                    entryClass = type(resultsDict[conditionEntry])
×
1224
                    conditionDict[conditionEntry] = entryClass(conditionDict[conditionEntry])
×
1225
                    conditionList.append(conditionDict[conditionEntry] == resultsDict[conditionEntry])
×
1226

1227
                if all(conditionList):
×
1228
                    # if equationVariable not in seriesColors.keys():
1229
                    #    seriesColors[equationVariable] = colors[colorsCounter]
1230
                    #    colorsCounter += 1
1231

1232
                    if "[" not in xAxisVariable:
×
1233
                        xAxis = resultsDict[xAxisVariable]
×
1234
                    else:
1235
                        name, index = str(xAxisVariable).split("[")
×
1236
                        index = int(index.replace("]", ""))
×
1237
                        xAxis = resultsDict[name][index]
×
1238
                    if "[" not in yAxisVariable:
×
1239
                        yAxis = resultsDict[yAxisVariable]
×
1240
                    else:
1241
                        name, index = str(yAxisVariable).split("[")
×
1242
                        index = int(index.replace("]", ""))
×
1243
                        yAxis = resultsDict[name][index]
×
1244

1245
                    chunkVariable = ""
×
1246

1247
                    if resultsDict[chunkVariable] not in plotXDict.keys():
×
1248
                        plotXDict[resultsDict[chunkVariable]] = {}
×
1249
                        plotYDict[resultsDict[chunkVariable]] = {}
×
1250
                        plotXDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]] = [xAxis]
×
1251
                        plotYDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]] = [yAxis]
×
1252
                    elif resultsDict[calculationVariable] not in plotXDict[resultsDict[chunkVariable]].keys():
×
1253
                        plotXDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]] = [xAxis]
×
1254
                        plotYDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]] = [yAxis]
×
1255
                    else:
1256
                        plotXDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]].append(xAxis)
×
1257
                        plotYDict[resultsDict[chunkVariable]][resultsDict[calculationVariable]].append(yAxis)
×
1258

1259
                else:
1260
                    pass
×
1261

1262
            for variable in calcVariableDict:
×
1263
                calcVariableDict[variable] = num.array(plotYDict[None][variable])
×
1264

1265
            calcVariableDict["equationDict"] = equationDict
×
1266
            for equation in equationDict:
×
1267
                calcVariableDict["equation"] = equation
×
1268
                exec("equationDict[equation]=" + equationDict[equation], calcVariableDict)
×
1269
                seriesColors[equation] = colors[colorsCounter]
×
1270
                colorsCounter += 1
×
1271
                colorsCounter = colorsCounter % len(colors)
×
1272

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

1293
            fig1, ax1 = plt.subplots(constrained_layout=True)
×
1294
            if self.inputs["plotStyle"] == "line":
×
1295
                styles = ["x-", "x--", "x-.", "x:", "o-", "o--", "o-.", "o:"]
×
1296
            elif self.inputs["plotStyle"] == "dot":
×
1297
                styles = ["x", "o", "+", "d", "s", "v", "^", "h"]
×
1298
            else:
1299
                print("Invalid 'plotStyle' argument")
×
1300

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

1314
                globalXAxisVariable = list(plotXDict[chunk].keys())[0]
×
1315
                index = num.argsort(plotXDict[chunk][globalXAxisVariable])
×
1316
                myX = num.array(plotXDict[chunk][globalXAxisVariable])[index]
×
1317
                mySize = len(myX)
×
1318

1319
                for key in equationDict.keys():
×
1320
                    myY = equationDict[key]
×
1321

1322
                    if key is not None and not isinstance(key, str):
×
1323
                        labelValue = round(float(key), 2)
×
1324
                    elif key is not None:
×
1325
                        labelValue = key
×
1326
                    if key is not None and labelValue not in labelSet:
×
1327
                        if not isinstance(labelValue, str):
×
1328
                            label = "{0:.1f}".format(labelValue)
×
1329
                        else:
1330
                            label = labelValue
×
1331
                            label = self.doc.getNiceLatexNames(label)
×
1332

1333
                        if "plotStyleJson" in self.inputs:
×
1334
                            plotKwargs = self.loadPlotJson(self.inputs["plotStyleJson"])
×
1335
                            plotStatement = (
×
1336
                                "ax1.plot(myX, myY,style, color=seriesColors[key], label=label" + plotKwargs + ")"
1337
                            )
1338
                            exec(plotStatement)
×
1339
                        else:
1340
                            ax1.plot(myX, myY, style, color=seriesColors[key], label=label)
×
1341
                    else:
1342
                        ax1.plot(myX, myY, style, color=seriesColors[key])
×
1343

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

1354
            for i in range(mySize):
×
1355
                for chunk, style in zip(plotXDict.keys(), styles):
×
1356
                    index = num.argsort(plotXDict[chunk][globalXAxisVariable])
×
1357
                    myX = num.array(plotXDict[chunk][globalXAxisVariable])[index]
×
1358
                    for key in equationDict.keys():  # the varables that appear in the legend
×
1359
                        myY = equationDict[key][index]
×
1360

1361
                        if type(myX[i]) == num.str_ and type(myY[i]) == num.str_:
×
1362
                            line = myX[i] + "\t" + myY[i] + "\t"
×
1363
                        elif type(myX[i]) == num.str_:
×
1364
                            line = myX[i] + "\t" + "%8.4f\t" % myY[i]
×
1365
                        elif type(myY[i]) == num.str_:
×
1366
                            line = "%8.4f\t" % myX[i] + myX[i] + "\t"
×
1367
                        else:
1368
                            line = "%8.4f\t%8.4f\t" % (myX[i], myY[i])
×
1369
                        lines = lines + line
×
1370

1371
                line = "\n"
×
1372
                lines = lines + line
×
1373

1374
            if chunkVariable != "":
×
1375
                legend2 = fig1.legend(
×
1376
                    [dummy_line[0] for dummy_line in dummy_lines],
1377
                    chunkLabels,
1378
                    title=self.doc.getNiceLatexNames(chunkVariable),
1379
                    bbox_to_anchor=(1.5, 1.0),
1380
                    bbox_transform=ax1.transAxes,
1381
                )
1382

1383
            else:
1384
                legend2 = None
×
1385
            if calculationVariable != "":
×
1386
                legend1 = fig1.legend(
×
1387
                    title=self.doc.getNiceLatexNames(calculationVariable),
1388
                    bbox_to_anchor=(1.2, 1.0),
1389
                    bbox_transform=ax1.transAxes,
1390
                )
1391

1392
            else:
1393
                legend1 = None
×
1394
            ax1.set_xlabel(self.doc.getNiceLatexNames(xAxisVariable))
×
1395
            ax1.set_ylabel(self.doc.getNiceLatexNames(yAxisVariable))
×
1396

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

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

1428
            plt.close()
×
1429

1430
            if self.inputs["setPrintDataForGle"]:
×
1431
                outfile = open(os.path.join(pathFolder, fileName + ".dat"), "w")
×
1432
                outfile.writelines(lines)
×
1433
                outfile.close()
×
1434

1435
    def scatterPlot(self):
×
1436
        pathFolder = self.inputs["pathBase"]
×
1437
        plotVariables = self.inputs["scatterPlot"][0]
×
1438
        differencePlot = False
×
1439
        xVariable = plotVariables[0]
×
1440
        yVariables = [plotVariables[1]]
×
1441
        if "-" in plotVariables[1]:
×
1442
            differencePlot = True
×
1443
            yVariables = plotVariables[1].split("-")
×
1444
        if len(plotVariables) > 2:
×
1445
            seriesVariable = plotVariables[2]
×
1446
        seriesVariable = ""
×
1447

1448
        if self.inputs["typeOfProcess"] == "json":
×
1449
            resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"), recursive=True)
×
1450
        else:
1451
            resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"))
×
1452

1453
        xDict = {}
×
1454
        yDict = {}
×
1455
        diffDict = {}
×
1456

1457
        for file in resultFiles:
×
1458
            with open(file) as f_in:
×
1459
                resultsDict = json.load(f_in)
×
1460
                resultsDict[""] = None
×
1461

1462
            if xVariable not in resultsDict:
×
1463
                continue
×
1464
            for variable in yVariables:
×
1465
                if variable not in resultsDict:
×
1466
                    continue
×
1467

1468
            if str(resultsDict[seriesVariable]) in xDict:
×
1469
                xDict[str(resultsDict[seriesVariable])].append(resultsDict[xVariable])
×
1470
                yDict[str(resultsDict[seriesVariable])].append(resultsDict[yVariables[0]])
×
1471
                if differencePlot:
×
1472
                    diffDict[str(resultsDict[seriesVariable])].append(resultsDict[yVariables[1]])
×
1473
            else:
1474
                xDict[str(resultsDict[seriesVariable])] = [resultsDict[xVariable]]
×
1475
                yDict[str(resultsDict[seriesVariable])] = [resultsDict[yVariables[0]]]
×
1476
                if differencePlot:
×
1477
                    diffDict[str(resultsDict[seriesVariable])] = [resultsDict[yVariables[1]]]
×
1478

1479
        self.doc = latex.LatexReport("", "")
×
1480
        if "latexNames" in self.inputs.keys():
×
1481
            if ":" in self.inputs["latexNames"]:
×
1482
                latexNameFullPath = self.inputs["latexNames"]
×
1483
            else:
1484
                latexNameFullPath = os.path.join(self.configPath, self.inputs["latexNames"])
×
1485
            self.doc.getLatexNamesDict(file=latexNameFullPath)
×
1486
        else:
1487
            self.doc.getLatexNamesDict()
×
1488

1489
        fig1, ax1 = plt.subplots(constrained_layout=True)
×
1490
        colors = plt.rcParams["axes.prop_cycle"].by_key()["color"]
×
1491
        colorsCounter = 0
×
1492

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

1534
        fileName = "scatter_*" + xVariable
×
1535
        for name in yVariables:
×
1536
            fileName += "_" + name
×
1537
        fileName += "_" + seriesVariable
×
1538
        fileName = re.sub(r"[^\w\-_\. ]", "", fileName)
×
1539

1540
        line = seriesVariable + "\t" + xVariable
×
1541
        for name in yVariables:
×
1542
            line += "\t" + name
×
1543
        lines = line + "\n"
×
1544
        for key in xDict:
×
1545
            for i in range(len(xDict[key])):
×
1546
                line = key + "\t" + str(xDict[key][i]) + "\t" + str(yDict[key][i])
×
1547
                if differencePlot:
×
1548
                    line += "\t" + str(diffDict[key][i])
×
1549
                lines += line + "\n"
×
1550

1551
        outfile = open(os.path.join(pathFolder, fileName + ".dat"), "w")
×
1552
        outfile.writelines(lines)
×
1553
        outfile.close()
×
1554

1555
        fig1.savefig(os.path.join(pathFolder, fileName + ".png"), bbox_inches="tight")
×
1556
        plt.close()
×
1557

1558
    def transferPathInfoToJson(self):
×
1559
        parDict = {}
×
1560
        for parList in self.inputs["pathInfoToJson"]:
×
1561
            parDict[parList[0]] = parList[1:]
×
1562

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

1566
        for file in resultFiles:
×
1567
            with open(file) as f_in:
×
1568
                resultsDict = json.load(f_in)
×
1569

1570
            for parName in parDict:
×
1571
                keyNotFound = True
×
1572
                for key in parDict[parName]:
×
1573
                    if key in file:
×
1574
                        resultsDict[parName] = key
×
1575
                        keyNotFound = False
×
1576
                if keyNotFound:
×
1577
                    resultsDict[parName] = ""
×
1578

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

1581
            with open(file, "w") as f_out:
×
1582
                json.dump(resultsDict, f_out, indent=2, separators=(",", ": "))
×
1583

1584
    def calculateInJson(self):
×
1585
        pathFolder = self.inputs["pathBase"]
×
1586
        resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"), recursive=True)
×
1587

1588
        for file in resultFiles:
×
1589
            with open(file) as f_in:
×
1590
                resultsDict = json.load(f_in)
×
1591

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

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

1604
            with open(file, "w") as f_out:
×
1605
                json.dump(resultsDict, f_out, indent=2, separators=(",", ": "))
×
1606

1607
    def insertIntoJson(self):
×
1608
        pathFolder = self.inputs["pathBase"]
×
1609
        resultFiles = glob.glob(os.path.join(pathFolder, "**/*-results.json"), recursive=True)
×
1610

1611
        for file in resultFiles:
×
1612
            with open(file) as f_in:
×
1613
                resultsDict = json.load(f_in)
×
1614

1615
            for item in self.inputs["jsonInsert"]:
×
1616
                resultsDict[item[0]] = item[1]
×
1617

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

1620
            with open(file, "w") as f_out:
×
1621
                json.dump(resultsDict, f_out, indent=2, separators=(",", ": "))
×
1622

1623
    def printBoxPlotGLEData(self):
×
1624
        pathFolder = self.inputs["pathBase"]
×
1625
        for SPFload in self.inputs["printBoxPlotGLEData"]:
×
1626
            SPF = SPFload[0]
×
1627

1628
            # SPF = plotVariables[0]
1629
            # SPFload = []
1630
            SPFValues = []
×
1631

1632
            for file in glob.glob(os.path.join(pathFolder, "**/*-results.json")):
×
1633
                with open(file) as f_in:
×
1634
                    resultsDict = json.load(f_in)
×
1635
                    # resultsDict[''] = None
1636
                    # name, index = str(SPF).split('[')
1637
                    # index = int(index.replace(']', ''))
1638

1639
                    SPFValue = resultsDict[SPF]
×
1640
                    SPFValues.append(SPFValue)
×
1641

1642
        SPFV = num.array(SPFValues)
×
1643

1644
        SPFQ25 = num.quantile(SPFV, 0.25)
×
1645
        SPFQ50 = num.quantile(SPFV, 0.5)
×
1646
        SPFQ75 = num.quantile(SPFV, 0.75)
×
1647
        SPFAv = num.average(SPFV)
×
1648
        SPFMin = num.min(SPFV)
×
1649
        SPFMax = num.max(SPFV)
×
1650

1651
        # line = "\n";
1652
        # lines = lines + line
1653

1654
        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)
×
1655
        outfileName = "yearSpfShpDisgle"
×
1656

1657
        outfile = open(os.path.join(pathFolder, outfileName + ".dat"), "w")
×
1658
        outfile.writelines(lines)
×
1659
        outfile.close()
×
1660

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

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

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

1742
    def changeFile(self, source, end):
×
1743
        # todo: this function is currently not working
1744

1745
        found = False
×
1746
        for i in range(len(self.lines)):
×
1747
            # self.lines[i].replace(source,end)
1748
            if self.lines[i] == source:
×
1749
                self.lines[i] = end
×
1750
                found = True
×
1751

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

1755
    def calcCost(self, fileNamesToRead=None):
×
1756
        resultsDirPath = _pl.Path(self.inputs["pathBase"])
×
1757
        configFilePath = _pl.Path(self.inputs["cost"])
×
1758
        shallWriteReport = self.inputs["costPdf"]
×
1759
        processType = _cc.OTHER if not fileNamesToRead else _cc.CasesDefined(fileNamesToRead)
×
1760
        _cc.calculateCostsAndWriteReports(configFilePath, resultsDirPath, shallWriteReport, processType)
×
1761

NEW
1762
    def collectJsonsIntoCsv(self, resultCsvFilePathString: str) -> None:
×
NEW
1763
        resultCsvFilePath = _pl.Path(resultCsvFilePathString)
×
NEW
1764
        resultsDirPath = _pl.Path(self.inputs["pathBase"])
×
NEW
1765
        _collect.collectJsonsIntoCsv(resultCsvFilePath, resultsDirPath)
×
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