source: TOOLS/ConsoGENCMIP6/bin/conso_gencmip6.py @ 2524

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

plot_store.py : plot initial volume in addition to current volume.

  • 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 json
10import shutil
11import os
12import os.path
13import subprocess
14# import datetime as dt
15
16# Application library imports
17from libconso import *
18
19
20########################################
21def get_storedir(login):
22
23  print("get_storedir")
24
25  command = ["ccc_home", "-A", "-u", login]
26  try :
27    res = subprocess.check_output(command)
28    print("res", res)
29  except Exception as rc:
30    print("exception", rc)
31    res = None
32
33  return res.strip()
34
35
36########################################
37def get_dirsize(dirname):
38
39  command = ["du", "-sbh", dirname]
40  try :
41    res = subprocess.check_output(command)
42    res = res.split()[0]
43  except Exception as rc :
44    print(rc)
45    res = None
46
47  return res
48
49
50# ########################################
51# def get_dirlist(dirname):
52
53
54#   return output
55
56
57########################################
58def parse_myproject(filename, project_name):
59
60  project = {}
61  project["name"] = project_name
62  logins  = {}
63
64  if where_we_run() == "curie":
65    try :
66      res = subprocess.check_output("ccc_myproject")
67    except Exception as rc :
68      print(rc)
69      exit(1)
70    with open(os.path.join(DIR["DATA"], OUT["CCCMP"]), "w") as fileout:
71      fileout.write(res)
72
73  with open(filename, "r") as filein:
74    # Skip lines until we find project name.
75    # Then extract script date
76    for ligne in filein:
77      if project["name"] in ligne:
78        today = ligne.split()[-1]
79        today = string_to_date(today)
80        project["machine"] = ligne.split()[5]
81        project["nodes"]   = ligne.split()[6]
82        break
83
84    # Skip next two lines : first is blank and second is login titles
85    for _ in xrange(1):
86      next(filein)
87
88    # Login list, until blank line
89    for ligne in filein:
90      if not ligne.strip():
91        break
92      login, conso = ligne.split()
93      logins[login] = float(conso)
94
95    # Skip until we find consumed time (hours)
96    for ligne in filein:
97      if "Total" in ligne:
98        total = float(ligne.split()[-1])
99        break
100
101    # Skip until we find allocated time (hours)
102    for ligne in filein:
103      if "Allocated" in ligne:
104        project["alloc"] = float(ligne.split()[-1])
105        break
106
107    # Skip until we find theoratical use (%)
108    for ligne in filein:
109      if "Suggested use at this time" in ligne:
110        utheo = float(ligne.split()[-1].strip("%"))
111        break
112
113    # Skip until we find real use (%)
114    for ligne in filein:
115      if "Real use at this time" in ligne:
116        ureal = float(ligne.split()[-1].strip("%"))
117        break
118
119    # Skip until we find deadline
120    for ligne in filein:
121      if "Project deadline" in ligne:
122        project["deadline"] = ligne.split()[-1]
123        break
124
125  return project, logins, today, total, utheo, ureal
126
127
128########################################
129def write_param(filename, project):
130
131  if args.dryrun:
132    print(json.dumps(project, indent=2))
133  else:
134    with open(filename, "w") as fileout:
135      json.dump(project, fileout, indent=2)
136
137
138########################################
139def write_bilan(filename, today, total, ureal, utheo,
140                run_mean, pen_mean, run_std, pen_std):
141  """
142  Conso totale par jour
143  ---------------------
144  on garde le total, date en tete en accumulant dans le fichier :
145  OUT_CONSO_BILAN
146  """
147
148  fmt_str = "{:10s} {:12s} {:11s} {:11s} {:13s} {:13s} {:13s} {:13s}\n"
149
150  title_str = fmt_str.format(
151    "date",
152    "conso(hours)",
153    "real_use(%)",
154    "theo_use(%)",
155    "running(core)",
156    "pending(core)",
157    "run_std(core)",
158    "pen_std(core)",
159  )
160
161  fmt_str = (
162    "{:%Y-%m-%d} {:12.2f} {:11.2f} {:11.2f} "
163    "{:13.2f} {:13.2f} {:13.2f} {:13.2f}\n"
164  )
165
166  result_str = fmt_str.format(
167    today,
168    total,
169    ureal,
170    utheo,
171    run_mean,
172    pen_mean,
173    run_std,
174    pen_std,
175  )
176
177  if args.dryrun:
178    print(title_str.strip())
179    print(result_str.strip())
180  else:
181    if not os.path.isfile(filename):
182      with open(filename, "w") as fileout:
183        fileout.write(title_str)
184    with open(filename, "a") as fileout:
185      fileout.write(result_str)
186
187
188########################################
189def write_utheo(filename, today, utheo):
190  """
191  Conso théorique par jour
192  ------------------------
193  OUT_CONSO_THEO
194  """
195
196  title_str  = "{:10s} {:11s}\n".format(
197                 "date",
198                 "theo_use(%)",
199               )
200  result_str = "{:%Y-%m-%d} {:11.2f}\n".format(
201                 today,
202                 utheo,
203               )
204
205  if args.dryrun:
206    print(title_str.strip())
207    print(result_str.strip())
208  else:
209    if not os.path.isfile(filename):
210      with open(filename, "w") as fileout:
211        fileout.write(title_str)
212    with open(filename, "a") as fileout:
213      fileout.write(result_str)
214
215
216########################################
217def write_login(filename, today, logins):
218  """
219  Conso par login (HOME)
220  ----------------------
221  on garde la trace de chaque login, date en tete, en remplacant
222  le fichier a chaque fois : OUT_CONSO_LOGIN
223  """
224
225  title_str  = "{:10s} {:10s} {:12s}\n".format(
226                 "date",
227                 "login",
228                 "conso(hours)",
229               )
230
231  with open(filename, "w") as fileout:
232    if args.dryrun:
233      print(title_str.strip())
234    else:
235      fileout.write(title_str)
236
237    for key in sorted(logins):
238      result_str = "{:%Y-%m-%d} {:10s} {:12.2f}\n".format(
239                     today,
240                     key,
241                     logins[key],
242                   )
243      if args.dryrun:
244        print(result_str.strip())
245      else:
246        fileout.write(result_str)
247
248
249########################################
250def write_store(filename, today, logins):
251  """
252  volume cree sur STORE
253  ---------------------
254  par login qui a consomme, en remplacant le fichier a chaque fois :
255  OUT_CONSO_STORE
256  """
257
258  items = (login for login, conso in logins.iteritems()
259                  if conso > 0.)
260
261  title_str = "{:10s} {:10s} {:>7s} {:s}\n".format(
262                "date",
263                "login",
264                "dirsize",
265                "dirname",
266              )
267
268  with open(filename, "w") as fileout:
269    if args.dryrun:
270      print(title_str.strip())
271    else:
272      fileout.write(title_str)
273
274    for login in items:
275      if args.verbose:
276        print(login)
277      storedir = get_storedir(login)
278      if not storedir:
279        print("storedir not found for {}".format(storedir))
280        break
281      igcm_out = os.path.join(storedir, "IGCM_OUT")
282
283      if not os.path.isdir(igcm_out):
284        print("no {}".format(igcm_out)) 
285        continue
286
287      dirlist = []
288      try:
289        dirlist = os.listdir(igcm_out)
290      except OSError as rc:
291        print("Error on os.listdir({}):\n{}".format(igcm_out, rc))
292
293      for dirname in dirlist:
294        result_str = "{:%Y-%m-%d} {:10s} {:>7s} {:s}\n".format(
295                       today,
296                       login,
297                       get_dirsize(os.path.join(igcm_out, dirname)),
298                       os.path.join(igcm_out, dirname)
299                     )
300
301        if args.dryrun or args.verbose:
302          print(result_str.strip())
303
304        if not args.dryrun:
305          fileout.write(result_str)
306
307
308########################################
309def save_files(file_list, today):
310
311  if not args.dryrun:
312    suffix = "{:%Y%m%d}".format(today)
313    for filename in file_list:
314      filein  = os.path.join(DIR["DATA"], filename)
315      if os.path.isfile(filein):
316        fileout = os.path.join(DIR["SAVEDATA"],
317                               "_".join((filename, suffix)))
318        shutil.copy(filein, fileout)
319
320
321########################################
322if __name__ == '__main__':
323
324  # Get arguments from command line
325  # ===============================
326  parser = ArgumentParser()
327  parser.add_argument("-v", "--verbose", action="store_true",
328                      help="Verbose mode")
329  parser.add_argument("-d", "--dryrun", action="store_true",
330                      help="dry run, no file produced")
331  parser.add_argument("-a", "--all", action="store_false",
332                      help="produce all files (default)")
333  parser.add_argument("-b", "--bilan", action="store_true",
334                      help="produce all files (default)")
335  parser.add_argument("-l", "--login", action="store_true",
336                      help="produce all files (default)")
337  parser.add_argument("-s", "--store", action="store_true",
338                      help="produce all files (default)")
339
340  args = parser.parse_args()
341  if args.verbose:
342    print(os.path.basename(__file__))
343    print(where_we_run())
344    print(args)
345
346  if args.bilan or args.login or args.store:
347    args.all = False
348
349  project_name, DIR, OUT = parse_config("bin/config.ini")
350
351  if args.verbose:
352    print(DIR["DATA"])
353    print(DIR["SAVEDATA"])
354
355  (project, logins, today, total, utheo, ureal) = parse_myproject(
356    os.path.join(DIR["DATA"], OUT["CCCMP"]),
357    project_name
358  )
359
360  if args.verbose:
361    print(today, utheo, ureal)
362    print(project)
363    print(logins)
364
365  # Produce files
366  # =============
367
368  # 1- Parametres du projet
369  # -----------------------
370  if args.verbose:
371    print("=> write_param")
372
373  write_param(os.path.join(DIR["DATA"], OUT["PARAM"]), project)
374
375  # 2- Conso totale par jour
376  # ------------------------
377
378  if args.verbose:
379    print("=> write_bilan")
380
381  file_jobs = get_last_file(
382      DIR["SAVEDATA"],
383      "{}_{:%Y%m%d}".format(OUT["JOBS"], today)
384  )
385  if args.verbose:
386    print(file_jobs)
387
388  run_mean = np.nan
389  pen_mean = np.nan
390  run_std  = np.nan
391  pen_std  = np.nan
392
393  if file_jobs:
394    try:
395      data = np.genfromtxt(
396        file_jobs,
397        skip_header=1,
398        converters={
399          0: string_to_datetime,
400          1: float,
401          2: float,
402        },
403        missing_values="nan",
404      )
405    except Exception as rc:
406      print("Problem with file {} :\n{}".format(file_jobs, rc))
407      exit(1)
408
409    run_mean = np.nanmean(
410        np.array([run for _, run, _ in data])
411    )
412    pen_mean = np.nanmean(
413        np.array([pen for _, _, pen in data])
414    )
415
416    run_std = np.nanstd(
417        np.array([run for _, run, _ in data])
418    )
419    pen_std = np.nanstd(
420        np.array([pen for _, _, pen in data])
421    )
422
423  if args.verbose:
424    print(run_mean, pen_mean, run_std, pen_std)
425
426  write_bilan(
427    os.path.join(DIR["DATA"], OUT["BILAN"]),
428    today,
429    total,
430    ureal,
431    utheo,
432    run_mean,
433    pen_mean,
434    run_std,
435    pen_std,
436  )
437
438  # 2b- Conso théorique par jour
439  # ----------------------------
440  if args.verbose:
441    print("=> write_utheo")
442
443  write_utheo(os.path.join(DIR["DATA"], OUT["UTHEO"]), today, utheo)
444
445  # 3- Conso par login (HOME)
446  # -------------------------
447  if args.verbose:
448    print("=> write_login")
449
450  write_login(os.path.join(DIR["DATA"], OUT["LOGIN"]), today, logins)
451
452  # 4- volume cree sur STORE
453  # ------------------------
454  if args.verbose:
455    print("=> write_store")
456
457  if where_we_run() == "curie":
458    write_store(os.path.join(DIR["DATA"], OUT["STORE"]), today, logins)
459
460  # Save files (on WORKDIR)
461  # =======================
462  if args.verbose:
463    print("=> Save files")
464  if not args.dryrun:
465    file_list = [
466        OUT["PARAM"],
467        OUT["BILAN"],
468        OUT["UTHEO"],
469        OUT["LOGIN"],
470        OUT["STORE"],
471        OUT["CCCMP"],
472    ]
473
474    save_files(file_list, today)
475
476  exit(0)
477
Note: See TracBrowser for help on using the repository browser.