source: TOOLS/ConsoGENCMIP6/bin/plot_jobs.py @ 2433

Last change on this file since 2433 was 2433, checked in by labetoulle, 7 years ago

cleaning

  • Property svn:executable set to *
File size: 10.5 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4# this must come first
5from __future__ import print_function, unicode_literals, division
6
7# standard library imports
8from argparse import ArgumentParser
9import os
10import os.path
11import datetime as dt
12import numpy as np
13
14# Application library imports
15from gencmip6 import *
16from gencmip6_path import *
17
18
19########################################
20class BilanDict(dict):
21  #---------------------------------------
22  def __init__(self):
23    self = {}
24
25  #---------------------------------------
26  def init_range(self, date_beg, date_end, inc=1):
27    """
28    """
29    delta = date_end - date_beg
30
31    (deb, fin) = (0, delta.days+1)
32
33    dates = (date_beg + dt.timedelta(days=i)
34             for i in xrange(deb, fin, inc))
35
36    for date in dates:
37      self.add_item(date)
38
39  #---------------------------------------
40  def fill_data(self, filein):
41    """
42    """
43    try:
44      data = np.genfromtxt(
45        filein,
46        skip_header=1,
47        converters={0: string_to_date,
48                    1: string_to_float,
49                    2: string_to_percent,
50                    3: string_to_percent},
51        missing_values="nan",
52      )
53    except:
54      print("Empty file {}".format(filein))
55      exit(1)
56
57    for date, conso, real_use, theo_use in data:
58      if date in self:
59        self.add_item(date, conso, real_use, theo_use)
60        self[date].fill()
61
62  #---------------------------------------
63  def add_item(self, date, conso=np.nan,
64               real_use=np.nan, theo_use=np.nan):
65    """
66    """
67    self[date] = Conso(date, conso, real_use, theo_use)
68
69  #---------------------------------------
70  def theo_equation(self):
71    """
72    """
73    (dates, theo_uses) = \
74      zip(*((item.date, item.theo_use)
75            for item in self.get_items_in_full_range()))
76
77    (idx_min, idx_max) = \
78        (np.nanargmin(theo_uses), np.nanargmax(theo_uses))
79
80    x1 = dates[idx_min].timetuple().tm_yday
81    x2 = dates[idx_max].timetuple().tm_yday
82
83    y1 = theo_uses[idx_min]
84    y2 = theo_uses[idx_max]
85
86    m = np.array([
87      [x1, 1.],
88      [x2, 1.]
89    ], dtype="float")
90    n = np.array([
91      y1,
92      y2
93    ], dtype="float")
94
95    try:
96      (a, b) = np.linalg.solve(m, n)
97    except np.linalg.linalg.LinAlgError:
98      (a, b) = (None, None)
99
100    if a and b:
101      for date in dates:
102        self[date].theo_equ = date.timetuple().tm_yday*a + b
103
104  #---------------------------------------
105  def get_items_in_range(self, date_beg, date_end, inc=1):
106    """
107    """
108    items = (item for item in self.itervalues()
109                   if item.date >= date_beg and
110                      item.date <= date_end)
111    items = sorted(items, key=lambda item: item.date)
112
113    return items[::inc]
114
115  #---------------------------------------
116  def get_items_in_full_range(self, inc=1):
117    """
118    """
119    items = (item for item in self.itervalues())
120    items = sorted(items, key=lambda item: item.date)
121
122    return items[::inc]
123
124  #---------------------------------------
125  def get_items(self, inc=1):
126    """
127    """
128    items = (item for item in self.itervalues()
129                   if item.isfilled())
130    items = sorted(items, key=lambda item: item.date)
131
132    return items[::inc]
133
134
135class Conso(object):
136  #---------------------------------------
137  def __init__(self, date, conso=np.nan,
138               real_use=np.nan, theo_use=np.nan):
139    self.date     = date
140    self.conso    = conso
141    self.real_use = real_use
142    self.theo_use = theo_use
143    self.theo_equ = np.nan
144    self.filled   = False
145
146  #---------------------------------------
147  def __repr__(self):
148    return "{:.2f} ({:.2%})".format(self.conso, self.real_use)
149
150  #---------------------------------------
151  def isfilled(self):
152    return self.filled
153
154  #---------------------------------------
155  def fill(self):
156    self.filled = True
157
158
159########################################
160def plot_init():
161  paper_size  = np.array([29.7, 21.0])
162  fig, ax = plt.subplots(figsize=(paper_size/2.54))
163
164  return fig, ax
165
166
167########################################
168def plot_data(ax, xcoord, xlabels, run_jobs, pen_jobs, conso_per_day):
169  """
170  """
171  line_width = 0.
172
173  ax.bar(xcoord, run_jobs, align="center", color="lightgreen",
174         linewidth=line_width, label="jobs running")
175  ax.bar(xcoord, pen_jobs, bottom=run_jobs, align="center",
176         color="indianred", linewidth=line_width, label="jobs pending")
177
178  ax.axhline(y=conso_per_day, color="blue", alpha=0.5,
179             label="conso journaliÚre idéale")
180
181
182########################################
183def plot_config(ax, xcoord, xlabels, title):
184  """
185  """
186  # ... Config axes ...
187  # -------------------
188  # 1) Range
189  xmin, xmax = xcoord[0]-1, xcoord[-1]+1
190  ax.set_xlim(xmin, xmax)
191  # ax.set_ylim(0., ymax)
192
193  # 2) Ticks labels
194  # inc_label = 12
195  # ax.ticklabel_format(axis="y", style="sci", scilimits=(0, 0))
196  xcoord_maj = [x for x, l in zip(xcoord, xlabels)
197                   if l.hour == 0 or l.hour == 12]
198  xlabels_maj = ["{:%d-%m %Hh}".format(l) for l in xlabels
199                 if l.hour == 0 or l.hour == 12]
200  ax.set_xticks(xcoord, minor=True)
201  ax.set_xticks(xcoord_maj, minor=False)
202  ax.set_xticklabels(xlabels_maj, rotation="vertical", size="x-small")
203
204  # 3) Define axes title
205  ax.set_ylabel("cœurs", fontweight="bold")
206
207  # ... Main title and legend ...
208  # -----------------------------
209  ax.set_title(title, fontweight="bold", size="large")
210  ax.legend(loc="best", fontsize="x-small", frameon=False)
211
212
213########################################
214def get_arguments():
215  parser = ArgumentParser()
216  parser.add_argument("-v", "--verbose", action="store_true",
217                      help="verbose mode")
218  parser.add_argument("-s", "--show", action="store_true",
219                      help="interactive mode")
220  parser.add_argument("-d", "--dods", action="store_true",
221                      help="copy output on dods")
222
223  return parser.parse_args()
224
225
226########################################
227if __name__ == '__main__':
228
229  # .. Initialization ..
230  # ====================
231  # ... Command line arguments ...
232  # ------------------------------
233  args = get_arguments()
234  if args.verbose:
235    print(args)
236
237  # ... Turn interactive mode off ...
238  # ---------------------------------
239  if not args.show:
240    import matplotlib
241    matplotlib.use('Agg')
242
243  import matplotlib.pyplot as plt
244  # from matplotlib.backends.backend_pdf import PdfPages
245
246  if not args.show:
247    plt.ioff()
248
249  # ... Files and directories ...
250  # -----------------------------
251  (file_param, file_utheo) = \
252      get_input_files(DIR["SAVEDATA"], [OUT["PARAM"], OUT["UTHEO"]])
253
254  img_name = "jobs"
255  today = os.path.basename(file_param).strip(OUT["PARAM"])
256
257  if args.verbose:
258    print(file_param)
259    print(file_utheo)
260    # print(file_data)
261    print(today)
262    print(img_name)
263
264  file_list = glob.glob(os.path.join(DIR["SAVEDATA"],
265                                     "OUT_JOBS_PENDING_*"))
266
267  fg_first = True
268
269  for filein in sorted(file_list):
270    try:
271      data = np.genfromtxt(
272        filein,
273        skip_header=1,
274        converters={
275          0: string_to_datetime,
276          1: int,
277          2: int,
278        },
279        missing_values="nan",
280      )
281    except Exception as rc:
282      print("Problem with file {} :\n{}".format(filein, rc))
283      exit(1)
284
285    if fg_first:
286      fg_first = False
287      full_data = data
288    else:
289      full_data = np.append(full_data, values=data)
290
291  # .. Get project info ..
292  # ======================
293  gencmip6 = Project()
294  gencmip6.fill_data(file_param)
295  gencmip6.get_date_init(file_utheo)
296
297  # .. Fill in conso data ..
298  # ========================
299  # # ... Initialization ...
300  # # ----------------------
301  # bilan = BilanDict()
302  # bilan.init_range(gencmip6.date_init, gencmip6.deadline)
303  # # ... Extract data from file ...
304  # # ------------------------------
305  # bilan.fill_data(file_data)
306  # # ... Compute theoratical use from known data  ...
307  # # ------------------------------------------------
308  # bilan.theo_equation()
309
310  # # .. Extract data depending on C.L. arguments ..
311  # # ==============================================
312  # if args.full:
313  #   selected_items = bilan.get_items_in_full_range(args.inc)
314  # elif args.range:
315  #   selected_items = bilan.get_items_in_range(
316  #     args.range[0], args.range[1], args.inc
317  #   )
318  # else:
319  #   selected_items = bilan.get_items(args.inc)
320
321  # .. Compute data to be plotted ..
322  # ================================
323  # nb_items = len(selected_items)
324  nb_items = full_data.size
325
326  xcoord   = np.linspace(1, nb_items, num=nb_items)
327  if full_data.size > 1:
328    xlabels  = np.array([date for date, run, pen in full_data])
329    run_jobs = np.array([run for date, run, pen in full_data],
330                          dtype=int)
331    pen_jobs = np.array([pen for date, run, pen in full_data],
332                          dtype=int)
333  else:
334    xlabels , run_jobs, pen_jobs = full_data.tolist()
335    xlabels = list(xlabels)
336    run_jobs = list(run_jobs )
337    pen_jobs = list(pen_jobs )
338
339  # cumul     = np.array([item.conso for item in selected_items],
340  #                       dtype=float)
341  # consos    = []
342  # consos.append(cumul[0])
343  # consos[1:nb_items] = cumul[1:nb_items] - cumul[0:nb_items-1]
344  # consos    = np.array(consos, dtype=float)
345
346  conso_per_day = gencmip6.alloc / (gencmip6.days * 24.)
347
348  # theo_uses = np.array([100.*item.theo_use for item in selected_items],
349  #                      dtype=float)
350  # real_uses = np.array([100.*item.real_use for item in selected_items],
351  #                      dtype=float)
352  # theo_equs = np.array([100.*item.theo_equ for item in selected_items],
353  #                      dtype=float)
354
355  # .. Plot stuff ..
356  # ================
357  # ... Initialize figure ...
358  # -------------------------
359  (fig, ax) = plot_init()
360
361  # ... Plot data ...
362  # -----------------
363  plot_data(ax, xcoord, xlabels, run_jobs, pen_jobs, conso_per_day)
364
365  # # ... Tweak figure ...
366  # # --------------------
367  # if args.max:
368  #   ymax = gencmip6.alloc
369  # else:
370  #   ymax = np.nanmax(consos) + np.nanmax(consos)*.1
371
372  title = "Consommation {}\n({:%d/%m/%Y} - {:%d/%m/%Y})".format(
373    gencmip6.project.upper(),
374    gencmip6.date_init,
375    gencmip6.deadline
376  )
377
378  plot_config(ax, xcoord, xlabels, title)
379
380  # ... Save figure ...
381  # -------------------
382  img_in  = os.path.join(DIR["PLOT"], "{}.pdf".format(img_name))
383  img_out = os.path.join(DIR["SAVEPLOT"],
384                         "{}_{}.pdf".format(img_name, today))
385
386  plot_save(img_in, img_out, title)
387
388  # ... Publish figure on dods ...
389  # ------------------------------
390  if args.dods:
391    dods_cp(img_in)
392
393  if args.show:
394    plt.show()
395
396  exit(0)
397
Note: See TracBrowser for help on using the repository browser.