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

Last change on this file since 2462 was 2462, checked in by labetoulle, 7 years ago

cleaning

  • 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        break
280      igcm_out = os.path.join(storedir, "IGCM_OUT")
281
282      if not os.path.isdir(igcm_out):
283        break
284
285      dirlist = []
286      try:
287        dirlist = os.listdir(igcm_out)
288      except OSError as rc:
289        print("Error on os.listdir({}):\n{}".format(igcm_out, rc))
290
291      for dirname in dirlist:
292        result_str = "{:%Y-%m-%d} {:10s} {:>7s} {:s}\n".format(
293                       today,
294                       login,
295                       get_dirsize(os.path.join(igcm_out, dirname)),
296                       os.path.join(igcm_out, dirname)
297                     )
298
299        if args.dryrun or args.verbose:
300          print(result_str.strip())
301
302        if not args.dryrun:
303          fileout.write(result_str)
304
305
306########################################
307def save_files(file_list, today):
308
309  if not args.dryrun:
310    suffix = "{:%Y%m%d}".format(today)
311    for filename in file_list:
312      filein  = os.path.join(DIR["DATA"], filename)
313      if os.path.isfile(filein):
314        fileout = os.path.join(DIR["SAVEDATA"],
315                               "_".join((filename, suffix)))
316        shutil.copy(filein, fileout)
317
318
319########################################
320if __name__ == '__main__':
321
322  # Get arguments from command line
323  # ===============================
324  parser = ArgumentParser()
325  parser.add_argument("-v", "--verbose", action="store_true",
326                      help="Verbose mode")
327  parser.add_argument("-d", "--dryrun", action="store_true",
328                      help="dry run, no file produced")
329  parser.add_argument("-a", "--all", action="store_false",
330                      help="produce all files (default)")
331  parser.add_argument("-b", "--bilan", action="store_true",
332                      help="produce all files (default)")
333  parser.add_argument("-l", "--login", action="store_true",
334                      help="produce all files (default)")
335  parser.add_argument("-s", "--store", action="store_true",
336                      help="produce all files (default)")
337
338  args = parser.parse_args()
339  if args.verbose:
340    print(os.path.basename(__file__))
341    print(where_we_run())
342    print(args)
343
344  if args.bilan or args.login or args.store:
345    args.all = False
346
347  project_name, DIR, OUT = parse_config("bin/config.ini")
348
349  if args.verbose:
350    print(DIR["DATA"])
351    print(DIR["SAVEDATA"])
352
353  (project, logins, today, total, utheo, ureal) = parse_myproject(
354    os.path.join(DIR["DATA"], OUT["CCCMP"]),
355    project_name
356  )
357
358  if args.verbose:
359    print(today, utheo, ureal)
360    print(project)
361    print(logins)
362
363  # Produce files
364  # =============
365
366  # 1- Parametres du projet
367  # -----------------------
368  if args.verbose:
369    print("=> write_param")
370
371  write_param(os.path.join(DIR["DATA"], OUT["PARAM"]), project)
372
373  # 2- Conso totale par jour
374  # ------------------------
375
376  if args.verbose:
377    print("=> write_bilan")
378
379  file_jobs = get_last_file(
380      DIR["SAVEDATA"],
381      "{}_{:%Y%m%d}".format(OUT["JOBS"], today)
382  )
383  if args.verbose:
384    print(file_jobs)
385
386  run_mean = np.nan
387  pen_mean = np.nan
388  run_std  = np.nan
389  pen_std  = np.nan
390
391  if file_jobs:
392    try:
393      data = np.genfromtxt(
394        file_jobs,
395        skip_header=1,
396        converters={
397          0: string_to_datetime,
398          1: float,
399          2: float,
400        },
401        missing_values="nan",
402      )
403    except Exception as rc:
404      print("Problem with file {} :\n{}".format(file_jobs, rc))
405      exit(1)
406
407    if len(data) == 24:
408      run_mean = np.nanmean(
409          np.array([run for _, run, _ in data])
410      )
411      pen_mean = np.nanmean(
412          np.array([pen for _, _, pen in data])
413      )
414
415      run_std = np.nanstd(
416          np.array([run for _, run, _ in data])
417      )
418      pen_std = np.nanstd(
419          np.array([pen for _, _, pen in data])
420      )
421
422  if args.verbose:
423    print(run_mean, pen_mean, run_std, pen_std)
424
425  write_bilan(
426    os.path.join(DIR["DATA"], OUT["BILAN"]),
427    today,
428    total,
429    ureal,
430    utheo,
431    run_mean,
432    pen_mean,
433    run_std,
434    pen_std,
435  )
436
437  # 2b- Conso théorique par jour
438  # ----------------------------
439  if args.verbose:
440    print("=> write_utheo")
441
442  write_utheo(os.path.join(DIR["DATA"], OUT["UTHEO"]), today, utheo)
443
444  # 3- Conso par login (HOME)
445  # -------------------------
446  if args.verbose:
447    print("=> write_login")
448
449  write_login(os.path.join(DIR["DATA"], OUT["LOGIN"]), today, logins)
450
451  # 4- volume cree sur STORE
452  # ------------------------
453  if args.verbose:
454    print("=> write_store")
455
456  if where_we_run() == "curie":
457    write_store(os.path.join(DIR["DATA"], OUT["STORE"]), today, logins)
458
459  # Save files (on WORKDIR)
460  # =======================
461  if args.verbose:
462    print("=> Save files")
463  if not args.dryrun:
464    file_list = [
465        OUT["PARAM"],
466        OUT["BILAN"],
467        OUT["UTHEO"],
468        OUT["LOGIN"],
469        OUT["STORE"],
470        OUT["CCCMP"],
471    ]
472
473    save_files(file_list, today)
474
475  exit(0)
476
Note: See TracBrowser for help on using the repository browser.