source: TOOLS/ConsoGENCMIP6/bin/plot_store.py @ 3863

Last change on this file since 3863 was 2843, checked in by labetoulle, 8 years ago

[consogencmip6] data anonymization (store & logins)

  • Property svn:executable set to *
File size: 11.2 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 numpy as np
12# import matplotlib.pyplot as plt
13# from matplotlib.backends.backend_pdf import PdfPages
14
15# Application library imports
16from libconso import *
17
18
19########################################
20class DirVolume(object):
21  #---------------------------------------
22  def __init__(self, date, login, dirname, size, date_init, dirsize_init):
23    self.date = date
24    self.login = login
25    self.dirname = dirname
26    self.dirsize = size
27    self.date_init = date_init
28    self.dirsize_init = dirsize_init
29
30  #---------------------------------------
31  def __repr__(self):
32    return "{}={}-{}".format(self.dirname, self.dirsize, self.dirsize_init)
33
34
35########################################
36class StoreDict(dict):
37  #---------------------------------------
38  def __init__(self):
39    self = {}
40
41  #---------------------------------------
42  def fill_data(self, filein, fileinit):
43    """
44    """
45    try:
46      data = np.genfromtxt(
47        filein,
48        skip_header=1,
49        converters={
50          0: string_to_date,
51          1: str,
52          2: string_to_size_unit,
53          3: str,
54        },
55        missing_values="nan",
56      )
57    except Exception as rc:
58      print("Problem with file {} :\n{}".format(filein, rc))
59      exit(1)
60
61    try:
62      init = np.genfromtxt(
63        fileinit,
64        skip_header=1,
65        converters={
66          0: string_to_date,
67          1: str,
68          2: string_to_size_unit,
69          3: str,
70        },
71        missing_values="nan",
72      )
73    except Exception as rc:
74      print("Problem with file {} :\n{}".format(filein, rc))
75      exit(1)
76
77    for (date, login, dirsize, dirname), \
78        (date_init, _, dirsize_init, _) in zip(data, init):
79      self.add_item(
80        date, login, dirsize, dirname,
81        date_init, dirsize_init
82      )
83
84  #---------------------------------------
85  def add_item(self, date, login, dirsize, dirname, date_init, dirsize_init):
86    """
87    """
88    if login not in self:
89      self[login] = Login(date, login)
90    self[login].add_directory(
91      date, login, dirsize, dirname,
92      date_init, dirsize_init
93    )
94
95  #---------------------------------------
96  def get_items(self):
97    """
98    """
99    items = (subitem for item in self.itervalues()
100                     for subitem in item.listdir)
101    items = sorted(items, key=lambda item: item.login)
102
103    return items
104
105  #---------------------------------------
106  def get_items_by_name(self, pattern):
107    """
108    """
109    items = (subitem for item in self.itervalues()
110                     for subitem in item.listdir
111                      if pattern in subitem.dirname)
112    items = sorted(items, key=lambda item: item.login)
113
114    return items
115
116
117########################################
118class Login(object):
119  #---------------------------------------
120  def __init__(self, date, login):
121    self.date  = date
122    self.login = login
123    self.total = SizeUnit(0., "K")
124    self.listdir = []
125
126  #---------------------------------------
127  def __repr__(self):
128    return "{}/{:%F}: {}".format(self.login, self.date, self.listdir)
129
130  #---------------------------------------
131  def add_to_total(self, dirsize):
132    """
133    """
134    somme = self.total.convert_size("K").size + \
135            dirsize.convert_size("K").size
136    self.total = SizeUnit(somme, "K")
137
138  #---------------------------------------
139  def add_directory(self, date, login, dirsize, dirname,
140                    date_init, dirsize_init):
141    """
142    """
143    self.listdir.append(DirVolume(date, login, dirname, dirsize,
144                                  date_init, dirsize_init))
145    if isinstance(dirsize, SizeUnit):
146      self.add_to_total(dirsize)
147    elif args.verbose:
148      print("No size for {}, {}".format(login, dirname))
149
150
151########################################
152def get_aliases(alias_file):
153
154  res = {}
155
156  if os.path.isfile(alias_file):
157    try:
158      data = np.genfromtxt(
159        os.path.join(alias_file),
160        skip_header=2,
161        converters={
162          0: str,
163          1: str,
164          2: str,
165          3: str,
166        },
167        missing_values="",
168      )
169    except Exception as rc:
170      print("Empty file {}:\n{}".format(filein, rc))
171      exit(1)
172
173  for alias, login, _, _ in data:
174    res[login] = alias
175
176  return res
177
178
179########################################
180def plot_init():
181  paper_size  = np.array([29.7, 21.0])
182  fig, ax = plt.subplots(figsize=(paper_size/2.54))
183
184  return fig, ax
185
186
187########################################
188def plot_data(ax, coords, ylabels, values, values_init):
189  """
190  """
191  ax.barh(coords, values, align="center", color="orange",
192          linewidth=0.1, label="volume sur STORE ($To$)")
193  ax.barh(coords, values_init, align="center", color="linen",
194          linewidth=0.1, label="volume initial sur STORE ($To$)")
195
196
197########################################
198def plot_config(fig, ax, coords, ylabels, dirnames, title,
199                tot_volume, tot_volume_init, delta):
200  """
201  """
202  from matplotlib.ticker import AutoMinorLocator
203
204  # ... Config axes ...
205  # -------------------
206  # 1) Range
207  ymin, ymax = coords[0]-1, coords[-1]+1
208  ax.set_ylim(ymin, ymax)
209
210  # 2) Ticks labels
211  ax.ticklabel_format(axis="x", style="sci", scilimits=(0, 0))
212  ax.set_yticks(coords, minor=False)
213  ax.set_yticklabels(ylabels, size="xx-small", fontweight="bold")
214  ax.invert_yaxis()
215
216  minor_locator = AutoMinorLocator()
217  ax.xaxis.set_minor_locator(minor_locator)
218
219  xmin, xmax = ax.get_xlim()
220  xpos = xmin + (xmax-xmin)/50.
221  for (ypos, text) in zip(coords, dirnames):
222    ax.text(s=text, x=xpos, y=ypos, va="center", ha="left",
223                size="xx-small", color="gray", style="italic")
224
225  # 3) Define axes title
226  ax.set_xlabel("$To$", fontweight="bold")
227
228  # 4) Define plot size
229  fig.subplots_adjust(
230    left=0.08,
231    bottom=0.09,
232    right=0.93,
233    top=0.93,
234  )
235
236  # ... Main title and legend ...
237  # -----------------------------
238  ax.set_title(title, fontweight="bold", size="large")
239  ax.legend(loc="best", fontsize="x-small", frameon=False)
240
241  tot_label = "prod {} = {}\n({} - {})".format(
242    projet.project.upper(),
243    delta,
244    tot_volume,
245    tot_volume_init,
246  )
247  plt.figtext(x=0.95, y=0.93, s=tot_label, backgroundcolor="linen",
248              ha="right", va="bottom", fontsize="small")
249
250
251########################################
252def get_arguments():
253  parser = ArgumentParser()
254  parser.add_argument("-v", "--verbose", action="store_true",
255                      help="verbose mode")
256  parser.add_argument("-f", "--full", action="store_true",
257                      help="plot all the directories in IGCM_OUT" +
258                           "(default: plot IPSLCM6 directories)")
259  parser.add_argument("-p", "--pattern", action="store",
260                      default="IPSLCM6",
261                      help="plot the whole period")
262  parser.add_argument("-s", "--show", action="store_true",
263                      help="interactive mode")
264  parser.add_argument("-d", "--dods", action="store_true",
265                      help="copy output on dods")
266
267  return parser.parse_args()
268
269
270########################################
271if __name__ == '__main__':
272
273  # .. Initialization ..
274  # ====================
275  # ... Command line arguments ...
276  # ------------------------------
277  args = get_arguments()
278
279  # ... Turn interactive mode off ...
280  # ---------------------------------
281  if not args.show:
282    import matplotlib
283    matplotlib.use('Agg')
284
285  import matplotlib.pyplot as plt
286  # from matplotlib.backends.backend_pdf import PdfPages
287
288  if not args.show:
289    plt.ioff()
290
291  # ... Files and directories ...
292  # -----------------------------
293  project_name, DIR, OUT = parse_config("bin/config.ini")
294
295  (file_param, file_utheo, file_data) = \
296      get_input_files(DIR["SAVEDATA"],
297                      [OUT["PARAM"], OUT["UTHEO"], OUT["STORE"]])
298
299  (file_init, ) = \
300      get_input_files(DIR["DATA"], [OUT["SINIT"]])
301
302  alias_file = os.path.join(
303    "bin",
304    "alias_catalog.dat",
305  )
306
307  img_name = os.path.splitext(
308               os.path.basename(__file__)
309             )[0].replace("plot_", "")
310
311  today = os.path.basename(file_param).strip(OUT["PARAM"])
312
313  if args.verbose:
314    fmt_str = "{:10s} : {}"
315    print(fmt_str.format("args", args))
316    print(fmt_str.format("today", today))
317    print(fmt_str.format("file_param", file_param))
318    print(fmt_str.format("file_utheo", file_utheo))
319    print(fmt_str.format("file_data", file_data))
320    print(fmt_str.format("file_init", file_init))
321    print(fmt_str.format("img_name", img_name))
322
323  # .. Get alias info ..
324  # ====================
325  alias_dict = get_aliases(alias_file)
326
327  # .. Get project info ..
328  # ======================
329  projet = Project(project_name)
330  projet.fill_data(file_param)
331  projet.get_date_init(file_utheo)
332
333  # .. Fill in data ..
334  # ==================
335  stores = StoreDict()
336  stores.fill_data(file_data, file_init)
337
338  # .. Extract data depending on C.L. arguments ..
339  # ==============================================
340  if args.full:
341    selected_items = stores.get_items()
342  else:
343    selected_items = stores.get_items_by_name(args.pattern)
344
345  if args.verbose:
346    for item in selected_items:
347      fmt_str = "{:8s} " + 2*"{:%F} {} {:>18s} " + "{} "
348      print(
349        fmt_str.format(
350          item.login,
351          item.date,
352          item.dirsize,
353          item.dirsize.convert_size("K"),
354          item.date_init,
355          item.dirsize_init,
356          item.dirsize_init.convert_size("K"),
357          item.dirname,
358        )
359      )
360
361  # .. Compute data to be plotted ..
362  # ================================
363  ylabels = [
364    alias_dict[item.login] 
365    if item.login in alias_dict
366    else str(hash(item.login)) 
367    for item in selected_items
368  ]
369  values = np.array(
370    [item.dirsize.convert_size("T").size for item in selected_items],
371    dtype=float
372  )
373  values_init = np.array(
374    [item.dirsize_init.convert_size("T").size for item in selected_items],
375    dtype=float
376  )
377  dirnames = [
378    "/".join(item.dirname.split("/")[6:]) for item in selected_items
379  ]
380  date = selected_items[0].date
381
382  nb_items = len(ylabels)
383  coords  = np.linspace(1, nb_items, num=nb_items)
384
385  # .. Plot stuff ..
386  # ================
387  # ... Initialize figure ...
388  # -------------------------
389  (fig, ax) = plot_init()
390
391  # ... Plot data ...
392  # -----------------
393  plot_data(ax, coords, ylabels, values, values_init)
394
395  # ... Tweak figure ...
396  # --------------------
397  title = "Occupation {} de STORE par login\n{:%d/%m/%Y}".format(
398    projet.project.upper(),
399    date
400  )
401 
402  tot_volume = np.sum(values)
403  tot_volume_init = np.sum(values_init)
404  delta = tot_volume - tot_volume_init
405 
406  plot_config(fig, ax, coords, ylabels, dirnames, title,
407              SizeUnit(tot_volume, "T"),
408              SizeUnit(tot_volume_init, "T"),
409              SizeUnit(delta, "T"))
410
411  # ... Save figure ...
412  # -------------------
413  img_in  = os.path.join(DIR["PLOT"], "{}.pdf".format(img_name))
414  img_out = os.path.join(DIR["SAVEPLOT"],
415                         "{}_{}.pdf".format(img_name, today))
416
417  plot_save(img_in, img_out, title, DIR)
418
419  # ... Publish figure on dods ...
420  # ------------------------------
421  if args.dods:
422    if args.verbose:
423      print("Publish figure on dods")
424    dods_cp(img_in, DIR)
425
426  if args.show:
427    plt.show()
428
429  exit(0)
430
Note: See TracBrowser for help on using the repository browser.