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

Last change on this file since 2776 was 2776, checked in by labetoulle, 6 years ago

typos and cleaning

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