source: TOOLS/ConsoGENCI/trunk/bin/libconso.py @ 3083

Last change on this file since 3083 was 3083, checked in by labetoulle, 5 years ago

Overall update (typos, get_project_list.py, ...)

File size: 11.2 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4# ==================================================================== #
5# Author: Sonia Labetoulle                                             #
6# Contact: sonia.labetoulle _at_ ipsl.jussieu.fr                       #
7# Created: 2016                                                        #
8# History:                                                             #
9# Modification:                                                        #
10# ==================================================================== #
11
12# this must come first
13# from __future__ import print_function, unicode_literals, division
14from __future__ import print_function, division
15
16# standard library imports
17import socket
18import os
19import os.path
20import glob
21import subprocess
22import datetime as dt
23import numpy as np
24import ConfigParser as cp
25
26# Application library imports
27
28########################################################################
29
30# .. Constants and variables ..
31# =============================
32cm2in = 1. / 2.54
33
34
35########################################################################
36def dods_cp(img_out, img_name, DODS):
37  """
38  """
39  if not DODS["DIR"]:
40    print("DODS directory not defined")
41    return
42
43  # .. Convert pdf to temporary png ..
44  # ==================================
45  import matplotlib.pyplot as plt
46
47  img_png = img_out.replace(".pdf", "_tmp.png")
48  dpi = 200.
49
50  plt.savefig(
51    img_png,
52    dpi=dpi,
53    format="png",
54    # transparent=True,
55    # bbox_inches="tight",
56    # pad_inches=0.2 * cm2in,
57  )
58
59  # .. Copy files to dods server ..
60  # ===============================
61  # ... pdf file ...
62  # ----------------
63  command = [
64    "scp",
65    img_out,
66    "{}@{}:{}".format(
67      DODS["USER"],
68      DODS["SERVER"],
69      os.path.join(DODS["DIR"], "pdf", img_name + ".pdf")
70    )
71  ]
72  print(command)
73  try:
74    subprocess.call(command)
75  except Exception as rc:
76    print("Error in scp for {}:\n{}".format(command, rc))
77
78  # ... png file ...
79  # ----------------
80  command = [
81    "scp",
82    img_png,
83    "{}@{}:{}".format(
84      DODS["USER"],
85      DODS["SERVER"],
86      os.path.join(DODS["DIR"], "img", img_name + ".png")
87    )
88  ]
89
90  print(command)
91  try:
92    subprocess.call(command)
93  except Exception as rc:
94    print("Error in scp for {}:\n{}".format(command, rc))
95
96  # .. Delete temporary png file ..
97  # ===============================
98  try:
99    os.remove(img_png)
100  except Exception as rc:
101    print("Could not remove {}:\n{}".format(img_png, rc))
102
103  return
104
105
106########################################################################
107def parse_config(filename):
108
109  DIR = {}
110  DODS = {}
111
112  config = cp.ConfigParser(allow_no_value=True)
113  config.optionxform = str
114  config.read(filename)
115
116  for section in ("projet", "directories"):
117    if not config.has_section(section):
118      print(
119        "Missing section {} in {}, we stop".format(section, filename)
120      )
121      exit(9)
122
123  # ... Project name ...
124  # --------------------
125  section = "projet"
126  option  = "name"
127  # project_name = config.get(section, option)
128
129  # ... Common directories ...
130  # --------------------------
131  section = "directories"
132  for option in config.options(section):
133    DIR[option] = config.get(section, option)
134
135    if DIR[option] and not os.path.isdir(DIR[option]):
136      print("mkdir {}".format(DIR[option]))
137      try:
138        os.makedirs(DIR[option])
139      except Exception as rc:
140        print("Could not create {}:\n{}".format(DIR[option], rc))
141
142  # .. DODS configuration ...
143  # -------------------------
144  section = "dods"
145  for option in config.options(section):
146    DODS[option] = config.get(section, option)
147
148  return (DIR, DODS)
149
150
151########################################################################
152def string_to_percent(x):
153  """
154  """
155  return float(x.strip("%"))/100.
156
157
158########################################################################
159def string_to_size_unit(x):
160  """
161  """
162  if unicode(x).isdecimal():
163    x = x + "o"
164
165  (size, unit) = (float(x[:-1]), x[-1])
166
167  return SizeUnit(size, unit)
168
169
170########################################################################
171def string_to_float(x):
172  """
173  """
174  return float(x.strip("h"))
175
176
177########################################################################
178def string_to_date(ssaammjj, fmt="%Y%m%d"):
179  """
180  """
181  fmts = ["%Y%m%d", "%Y-%m-%d", "%Y_%m_%d"]
182
183  for fmt in fmts:
184    try:
185      res = dt.datetime.strptime(ssaammjj, fmt)
186    except Exception:
187      pass
188    else:
189      break
190
191  return res.date()
192
193
194########################################################################
195def string_to_datetime(string, fmt="%Y-%m-%d-%H:%M"):
196  """
197  """
198  return dt.datetime.strptime(string, fmt)
199
200
201########################################################################
202def where_we_run():
203
204  res = ""
205  if "curie" in socket.getfqdn():
206    res = "curie"
207  elif "ipsl" in socket.getfqdn():
208    res = "ipsl"
209  else:
210    res = "default"
211
212  return res
213
214
215########################################################################
216def get_last_file(dir_data, pattern):
217  """
218  """
219  current_dir = os.getcwd()
220  os.chdir(dir_data)
221  filename = pattern + "*"
222  file_list = glob.glob(os.path.join(dir_data, filename))
223  if file_list:
224    res = sorted(file_list)[-1]
225  else:
226    res = None
227  os.chdir(current_dir)
228  return res
229
230
231########################################################################
232def get_input_files(dir_data, file_list):
233  """
234  """
235  res = []
236
237  for filename in file_list:
238    res.append(get_last_file(dir_data, filename))
239
240  if None in res:
241    print("\nMissing one or more input files, we stop.")
242    for f_in, f_out in zip(file_list, res):
243      print("=> {}: {}".format(f_in, f_out))
244    exit(9)
245
246  return res
247
248
249########################################################################
250def plot_save(img_out, title, png=False):
251  """
252  """
253  import matplotlib.pyplot as plt
254  from matplotlib.backends.backend_pdf import PdfPages
255
256  dpi = 200.
257
258  dirname = os.path.dirname(img_out)
259  if not os.path.isdir(dirname):
260    print("mkdir {}".format(dirname))
261    try:
262      os.makedirs(dirname)
263    except Exception as rc:
264      print("Could not create {}:\n{}".format(dirname, rc))
265
266  if png:
267    img_png = img_out.replace(".pdf", ".png")
268    plt.savefig(
269      img_png,
270      dpi=dpi,
271      format="png",
272      # transparent=True,
273      # bbox_inches="tight",
274      # pad_inches=0.2 * cm2in,
275    )
276
277  with PdfPages(img_out) as pdf:
278    pdf.savefig(dpi=dpi)
279
280    # ... pdf file's metadata ...
281    # ---------------------------
282    d = pdf.infodict()
283    d["Title"]   = title
284    d["Author"]  = os.path.basename(__file__)
285
286    # d["Subject"] = (
287    #   "Time spent over specific commands during create_ts "
288    #   "jobs at IDRIS and four configurations at TGCC"
289    # )
290    # d["Keywords"] = "bench create_ts TGCC IDRIS ncrcat"
291    # d["CreationDate"] = dt.datetime(2009, 11, 13)
292    # d["ModDate"] = dt.datetime.today()
293
294
295########################################################################
296class AllocItem(object):
297
298  # --------------------------------------------------------------------
299  def __init__(
300    self,
301    alloc_id,
302    machine,
303    node_type,
304    start_date,
305    end_date,
306    alloc
307  ):
308
309    self.alloc_id   = alloc_id
310    self.machine    = machine
311    self.node_type  = node_type
312    self.start_date = start_date
313    self.end_date   = end_date
314    self.alloc      = alloc
315
316    delta = self.end_date - self.start_date
317    self.days = delta.days + 1
318
319    self.daily_conso = self.alloc / self.days
320
321  # --------------------------------------------------------------------
322  def __repr__(self):
323    return "{} ({:%Y%m%d}/{:%Y%m%d}): {}".format(
324      self.machine,
325      self.start_date,
326      self.end_date,
327      self.alloc,
328    )
329
330
331########################################################################
332class Project(object):
333
334  # --------------------------------------------------------------------
335  def __init__(self, project_name, center):
336    self.project = project_name
337    self.centre = center
338    self.alloc_items = []
339
340  # --------------------------------------------------------------------
341  def __repr__(self):
342    return "{}/{}: {}".format(
343      self.project,
344      self.centre,
345      self.alloc_items,
346    )
347
348  # --------------------------------------------------------------------
349  def add_alloc(
350    self,
351    alloc_id,
352    machine,
353    node_type,
354    start_date,
355    end_date,
356    alloc
357  ):
358
359    alloc_item = AllocItem(
360      alloc_id,
361      machine,
362      node_type,
363      start_date,
364      end_date,
365      alloc
366    )
367
368    self.alloc_items.append(alloc_item)
369
370    self.start_date = min(
371      [item.start_date for item in self.alloc_items]
372    )
373    self.end_date = max(
374      [item.end_date for item in self.alloc_items]
375    )
376
377    self.alloc = sum(
378      [item.alloc for item in self.alloc_items]
379    )
380    self.max_daily_conso = max(
381      [item.daily_conso for item in self.alloc_items]
382    )
383
384    self.days = sum(
385      [item.days for item in self.alloc_items]
386    )
387
388    self.nb_alloc = len(self.alloc_items)
389
390  # --------------------------------------------------------------------
391  def get_theo_eq(self, dates):
392
393    # x0 = 0
394    y0 = 0.
395
396    for item in self.alloc_items:
397      yi = y0
398      yf = y0 + item.alloc / self.alloc
399
400      if item.start_date.date() in dates:
401        xi = dates.index(item.start_date.date())
402      else:
403        xi = 0
404
405      if item.end_date.date() in dates:
406        xf = dates.index(item.end_date.date())
407      else:
408        xf = len(dates) + 1
409
410      m = np.array([[xi, 1.], [xf+1, 1.]])
411      n = np.array([yi, yf])
412
413      try:
414        polynome = np.poly1d(np.linalg.solve(m, n))
415      except np.linalg.linalg.LinAlgError:
416        print("error poly")
417        item.theo_eq = None
418      else:
419        item.theo_eq = polynome
420        item.xi = xi
421        item.xf = xf
422        item.yi = yi
423        item.yf = yf
424
425      y0 = yf
426
427  # --------------------------------------------------------------------
428  def fill_data(self, row):
429    # self.id = row["id"]
430    # self.machine = row["machine"]
431    # self.node = row["node_type"]
432    # self.start_date = row["start_date"]
433    # self.end_date = row["end_date"]
434    # self.alloc = row["total_hrs"]
435
436    delta = self.end_date - self.start_date
437    self.days = delta.days + 1
438
439
440########################################################################
441class SizeUnit(object):
442  # --------------------------------------------------------------------
443  def __init__(self, size, unit):
444    self.size = size
445    self.unit = unit
446
447  # --------------------------------------------------------------------
448  def __repr__(self):
449    return "{:6.2f}{}o".format(self.size, self.unit)
450
451  # --------------------------------------------------------------------
452  def convert_size(self, unit_out):
453    """
454    """
455    prefixes = ["o", "K", "M", "G", "T", "P", "H"]
456
457    if not self.size or \
458       self.unit == unit_out:
459      size_out = self.size
460    else:
461      idx_deb = prefixes.index(self.unit)
462      idx_fin = prefixes.index(unit_out)
463      size_out = self.size
464      for i in xrange(abs(idx_fin-idx_deb)):
465        if idx_fin > idx_deb:
466          size_out = size_out / 1024
467        else:
468          size_out = size_out * 1024
469
470    return SizeUnit(size_out, unit_out)
471
472
473########################################################################
474if __name__ == '__main__':
475  pass
Note: See TracBrowser for help on using the repository browser.