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

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

Overall cleaning and refactoring

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