1# -*- coding: utf-8 -*-
2
3#-------------------------------------------------------------------------------
4
5# This file is part of Code_Saturne, a general-purpose CFD tool.
6#
7# Copyright (C) 1998-2021 EDF S.A.
8#
9# This program is free software; you can redistribute it and/or modify it under
10# the terms of the GNU General Public License as published by the Free Software
11# Foundation; either version 2 of the License, or (at your option) any later
12# version.
13#
14# This program is distributed in the hope that it will be useful, but WITHOUT
15# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17# details.
18#
19# You should have received a copy of the GNU General Public License along with
20# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
21# Street, Fifth Floor, Boston, MA 02110-1301, USA.
22
23#-------------------------------------------------------------------------------
24
25#-------------------------------------------------------------------------------
26# Standard modules import
27#-------------------------------------------------------------------------------
28
29import os
30
31#-------------------------------------------------------------------------------
32# Application modules import
33#-------------------------------------------------------------------------------
34
35from code_saturne.studymanager.cs_studymanager_run import run_studymanager_command
36
37#-------------------------------------------------------------------------------
38
39class TexWriter(object):
40    """
41    """
42    def __init__(self, dest, filename, log, pdflatex):
43        self.__dest = dest
44        self.__filename = os.path.join(self.__dest, filename)
45        self.__doc = []
46        self.__log = log
47        self.__pdflatex = pdflatex
48
49
50    def rawLine(self, line):
51        self.__doc.append(line)
52
53
54    def appendLine(self, line):
55        line = line.replace("_", "\_")
56        self.__doc.append("%s \n" % (line))
57
58
59    def addFigure(self, g):
60        self.__doc.append("\\begin{center}\n")
61        self.__doc.append("\\includegraphics[width=0.99\\textwidth]{%s}\n" % g)
62        self.__doc.append("\\end{center}\n")
63
64
65    def addInput(self, filename):
66        self.appendLine("\n\\begin{verbatim}")
67        f = open(filename)
68        self.rawLine(f.read())
69        f.close()
70        self.appendLine("\\end{verbatim}\n")
71
72
73    def addTexInput(self, filename):
74        f = open(filename)
75        self.rawLine(f.read())
76        f.close()
77
78
79    def tabCreate(self, columns):
80        assert type(columns) == list
81
82        self.__doc.append("\\begin{center}\n")
83        s = "l|"*len(columns)
84        self.__doc.append("\\begin{longtable}{|%s}\n" % s)
85        self.__doc.append("\hline\n")
86
87        for i in range(len(columns)):
88            if i != len(columns)-1:
89                self.__doc.append("\\textbf{%s} &" % (columns[i]))
90            else:
91                self.__doc.append("\\textbf{%s} \\\ \n" % (columns[i]))
92
93        self.__doc.append("\hline\n")
94        self.__doc.append("\hline\n")
95
96
97    def tabWrite(self, columns):
98        assert type(columns) == list
99
100        for i in range(len(columns)):
101            if columns[i] == "OK":
102                columns[i] = "\\textcolor{green}{OK}"
103            elif columns[i] == "KO":
104                columns[i] = "\\textcolor{red}{KO}"
105            elif columns[i] == None:
106                columns[i] = "\\textit{default}"
107
108            if i != len(columns)-1:
109                self.__doc.append("%s &" % (columns[i]))
110            else:
111                self.__doc.append("%s \\\ \n" % (columns[i]))
112
113        self.__doc.append("\hline\n")
114
115
116    def tabClose(self):
117        self.__doc.append("\\end{longtable}\n")
118        self.__doc.append("\\end{center}\n")
119
120
121    def write(self):
122        # header
123        head = []
124        head.append("\\documentclass[a4paper, 10pt]{article}\n")
125        head.append("\\usepackage[latin1]{inputenc}\n")
126        head.append("\\usepackage[T1]{fontenc}\n")
127        head.append("\\usepackage[normalem]{ulem}\n")
128        head.append("\\usepackage[french]{babel}\n")
129        head.append("\\usepackage{verbatim}\n")
130        head.append("\\usepackage{color}\n")
131        head.append("\\usepackage{longtable}\n")
132        head.append("\\usepackage{listings}\n")
133        head.append("\\usepackage{ifpdf}\n")
134        head.append("\\usepackage{tikz}\n")
135        head.append("\\usepackage{pgfplots}\n")
136        head.append("\\pgfplotsset{\n")
137        head.append("compat=newest,\n")
138        head.append("xlabel near ticks,\n")
139        head.append("ylabel near ticks\n")
140        head.append("}\n")
141        head.append("\\setlength{\\voffset}{0pt}")
142        head.append("\\setlength{\\topmargin}{0pt}")
143        head.append("\\addtolength{\\topmargin}{-13mm}")
144        head.append("\\setlength{\\headheight}{15mm}")
145        head.append("\\setlength{\\headsep}{6mm}")
146        head.append("\\setlength{\\textheight}{233mm}")
147        head.append("\\setlength{\\footskip}{15mm}")
148        head.append("\\setlength{\\hoffset}{0pt}")
149        head.append("\\setlength{\\evensidemargin}{0mm}")
150        head.append("\\setlength{\\oddsidemargin}{0mm}")
151        head.append("\\setlength{\\textwidth}{162mm}")
152        head.append("\\setlength{\\parindent}{0mm}")
153        head.append("\\setlength{\\parskip}{6pt}")
154        head.append("\\setlength{\\tabcolsep}{1mm}")
155
156
157        head.append("\\begin{document}\n")
158
159        # end
160        tail = []
161        tail.append("\\end{document} \n")
162
163        # write
164        f = open(self.__filename + ".tex", mode='w')
165        f.writelines(head + self.__doc + tail)
166        f.close()
167
168
169    def make_pdf(self):
170        """
171        Buld the pdf file, and clean the temporary files.
172        """
173        cmd = "pdflatex " + self.__filename + ".tex"
174        r, t = run_studymanager_command(cmd, self.__log)
175
176        for suffixe in ["tex", "log", "aux"]:
177            f = self.__filename + "." + suffixe
178            if os.path.isfile(f):
179                os.remove(self.__filename + "." + suffixe)
180
181        return self.__filename + ".pdf"
182
183
184    def tex_finalize(self):
185        """
186        Finalize by making pdf if pdflatex is enabled,
187        returns pdf file name (or tex file name if pdflatex disabled).
188        """
189        if self.__pdflatex:
190            filename = self.make_pdf()
191        else:
192            filename = self.__filename + ".tex"
193
194        return filename
195
196#-------------------------------------------------------------------------------
197
198class Report1(TexWriter):
199    """
200    Global report.
201    """
202    def __init__(self, dest, label, log, report, xml, pdflatex):
203        TexWriter.__init__(self, dest, label, log, pdflatex)
204        self.appendLine("\\section{Summary}")
205        self.tabCreate(["Study / Case", "Compilation", "Run", "Time (s)", "Difference"])
206        self.xml = xml
207        self.report = report
208
209
210    def add_row(self, studyLabel, caseLabel, is_compil, is_run, is_time, is_compare, is_diff):
211        if is_compare == "not done":
212            threshold = "Not used"
213            is_diff   = "Not used"
214
215        label = "%s / %s" % (studyLabel, caseLabel)
216        label = label.replace("_", "\_")
217        self.tabWrite([label, is_compil, is_run, is_time, is_diff])
218
219
220    def close(self):
221        self.tabClose()
222
223        self.appendLine("\\section{Log}")
224        self.appendLine("\\tiny\n\\begin{verbatim}")
225        f = open(self.report)
226        self.rawLine(f.read())
227        f.close()
228        self.appendLine("\\end{verbatim}\n\\normalsize")
229
230        self.appendLine("\\section{File of commands}")
231        self.appendLine("\\tiny\n\\begin{verbatim}")
232        self.rawLine(self.xml)
233        self.appendLine("")
234        self.appendLine("\\end{verbatim}\n\\normalsize")
235
236        self.write()
237
238        return self.tex_finalize()
239
240#-------------------------------------------------------------------------------
241
242class Report2(TexWriter):
243    """
244    Detailed report.
245    """
246    def __init__(self, dest, label, log, pdflatex):
247        """
248        """
249        TexWriter.__init__(self, dest, label, log, pdflatex)
250
251
252    def add_row(self, values, studyLabel, caseLabel):
253        nbvalue = len(values)
254        row_max = 40
255
256        if nbvalue:
257            self.tabCreate(["Variable Name", "Diff. Max", "Diff. Mean", "Threshold"])
258            for j in range(len(values)):
259                self.tabWrite([values[j][0], values[j][1], values[j][2], values[j][3]])
260
261            self.tabClose()
262            self.appendLine("\n \\newpage \n")
263
264
265    def close(self):
266        self.write()
267        return self.tex_finalize()
268
269#-------------------------------------------------------------------------------
270
271def test():
272    """
273    Test function.
274    The pupose is to build 2 documents:
275    1. a global report for all cases:
276    2. a detailled report for each case:
277    """
278
279    dest      = os.getcwd()
280    doc       = Report1(dest, "r1")
281    compil    = True
282    run       = True
283    compare   = True
284    diff      = True
285    repo      = True
286    threshold = 1.e-15
287    doc.add_row("MYSTUDY", "MYCASE", compil, run, compare, diff, repo, threshold)
288    doc.close()
289
290    msg = """
291  .----------------------------.
292  |   Code_Saturne file dump   |
293  `----------------------------'
294
295Opening input file: "RESU/20110217-2231/checkpoint/main"
296
297  File type: Checkpoint / restart, R0
298
299  Base header size: 128
300  Header alignment: 64
301  Body alignment:   64
302
303Opening input file: "RESU/20110217-2233/checkpoint/main"
304
305  File type: Checkpoint / restart, R0
306
307  Base header size: 128
308  Header alignment: 64
309  Body alignment:   64
310
311  "nbre_pas_de_temps               "; Location:  0; Type: i4    ; Size: 1
312    Differences: 1
313
314  "instant_precedent               "; Location:  0; Type: r8    ; Size: 1
315    Differences: 1; Max: 200; Mean: 200
316
317  "pression_ce_phase01             "; Location:  1; Type: r8    ; Size: 14574
318    Differences: 14574; Max: 3.09509; Mean: 0.159934
319
320  "vitesse_u_ce_phase01            "; Location:  1; Type: r8    ; Size: 14574
321    Differences: 14574; Max: 2.00929; Mean: 0.118064
322
323  "vitesse_v_ce_phase01            "; Location:  1; Type: r8    ; Size: 14574
324    Differences: 14574; Max: 1.84415; Mean: 0.065676
325
326  "vitesse_w_ce_phase01            "; Location:  1; Type: r8    ; Size: 14574
327    Differences: 14574; Max: 1.15005; Mean: 0.093984
328
329  "k_ce_phase01                    "; Location:  1; Type: r8    ; Size: 14574
330    Differences: 14574; Max: 2.49588; Mean: 0.0191537
331
332  "eps_ce_phase01                  "; Location:  1; Type: r8    ; Size: 14574
333    Differences: 14574; Max: 7438.13; Mean: 12.6477
334
335  "scalaire_ce_0001                "; Location:  1; Type: r8    ; Size: 14574
336    Differences: 14500; Max: 0.11862; Mean: 0.00345369
337
338    """
339
340    doc  = Report2(dest, "r2")
341    v    = []
342    info = msg.replace("\"", " ").replace(";", " ").replace(":", " ").split()
343    print(info)
344    repo = "RESU/20110217-2231/checkpoint/main"
345    dest = "RESU/20110217-2233/checkpoint/main"
346
347    for i in range(len(info)):
348        if info[i][:4] == 'Diff':
349            if info[i-3] not in ['i4', 'u4']:
350                v.append([info[i-7].replace("_", "\_"), info[i+3], info[i+5]])
351    print(v)
352    doc.add_row(v, "MYSTUDY", "MYCASE", threshold)
353    doc.close()
354
355
356if __name__ == '__main__':
357    test()
358
359#-------------------------------------------------------------------------------
360