source: TOOLS/ConsoGENCI/trunk/bin/libconso_cpt.py @ 2783

Last change on this file since 2783 was 2783, checked in by labetoulle, 6 years ago
  • Run everything (DB inserts + plots) from single bash script
  • Change exit codes (unsigned in bash, so no negative values...) :
    • 0: everything was ok;
    • 1: nothing done, 'cause nothing to do => ok;
    • >= 2: error.
  • DB access now needs password
  • plot_bilan: added date of production and plotted range to image
  • Cleaning (useless comments, ...)
  • Property svn:executable set to *
File size: 8.3 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# =================================================================== #
13# ssh readonly@prodiguer-test-db.ipsl.upmc.fr                         #
14# psql -U prodiguer_db_user prodiguer                                 #
15#                                                                     #
16# ssh readonly@prodiguer-test-db.ipsl.upmc.fr -L 5432:localhost:5432  #
17# =================================================================== #
18
19
20# This must come first
21from __future__ import print_function, unicode_literals, division
22
23# Standard library imports
24import os
25import glob
26import pprint
27
28# Application library imports
29
30pp = pprint.PrettyPrinter(indent=2)
31
32
33#######################################################################
34class ProjectBloc(object):
35
36  #--------------------------------------------------------------------
37  def __init__(
38    self,
39    name,
40    center,
41    machine=None,
42    node=None,
43    date_beg=None,
44    date_end=None,
45    alloc=None,
46    line_beg=None,
47    line_end=None,
48  ):
49    self.name     = name
50    self.center   = center
51    self.machine  = machine
52    self.node     = node
53    self.date_beg = date_beg
54    self.date_end = date_end
55    self.alloc    = alloc
56    self.line_beg = line_beg
57    self.line_end = line_end
58    self.alloc_id = None
59
60  #--------------------------------------------------------------------
61  def __repr__(self):
62    return "{}/{} = {}".format(
63      self.name,
64      self.center,
65      self.alloc,
66    )
67
68
69#######################################################################
70class ConsoItem(object):
71
72  #--------------------------------------------------------------------
73  def __init__(self, login, date, conso):
74    self.login = login
75    self.date  = date
76    self.conso = conso
77
78  #--------------------------------------------------------------------
79  def __repr__(self):
80    return "{}/{:%Y%m%d} = {}".format(
81      self.login,
82      self.date,
83      self.conso,
84    )
85
86
87#######################################################################
88class AllocRow(object):
89
90  #--------------------------------------------------------------------
91  def __init__(self, row):
92    self.name     = row["project"]
93    self.alloc_id = row["id"]
94    self.machine  = row["machine"]
95    self.centre   = row["centre"]
96    self.node     = row["node_type"]
97    self.date_beg = row["start_date"]
98    self.date_end = row["end_date"]
99    self.alloc    = row["total_hrs"]
100
101  #--------------------------------------------------------------------
102  def __repr__(self):
103    return "{}/{}/{:%Y%m%d}/{:%Y%m%d} ({})".format(
104      self.machine,
105      self.node,
106      self.date_beg,
107      self.date_end,
108      self.alloc_id,
109    )
110
111
112#######################################################################
113def get_project_id(bloc, allocs):
114
115  res = None
116
117  for alloc in allocs:
118    # print(
119    #   bloc.cpt_date,
120    #   alloc.date_end,
121    #   bloc.cpt_date <= alloc.date_end
122    # )
123    if bloc.machine == alloc.machine   and \
124       bloc.node == alloc.node         and \
125       bloc.cpt_date >= alloc.date_beg and \
126       bloc.cpt_date <= alloc.date_end:
127      res = alloc.alloc_id
128      break
129
130  return res
131
132
133#######################################################################
134def cpt_pattern(project, center):
135
136  return "cpt_{}_{}_*.dat".format(center, project)
137
138
139#######################################################################
140def parse_input_cpt(filename, project, center, mode_conso=False):
141
142  if center == "idris":
143    return parse_idris_cpt(filename, project)
144  elif center == "tgcc":
145    return parse_tgcc_cpt(filename, project, mode_conso)
146  else:
147    print("Unknown center {}".format(center))
148    exit(9)
149
150
151#######################################################################
152def parse_tgcc_cpt(filename, project, mode_conso=False):
153
154  import datetime as dt
155
156  # Determine first and last lines of project bloc(s),
157  # and basic project info
158  blocs = []
159  with open(filename, "r") as filein:
160    for num, ligne in enumerate(filein):
161      if "Accounting" in ligne:
162        _, _, _, name, _, machine, node, _, day = ligne.split()
163        bloc = ProjectBloc(
164          name.lower(),
165          "tgcc",
166          machine.lower(),
167          node.lower(),
168        )
169        bloc.cpt_date = dt.datetime.strptime(
170          "{} {}".format(day, "23:59"), "%Y-%m-%d %H:%M"
171        )
172        bloc.line_beg = num + 1
173      if "Allocated" in ligne:
174        bloc.alloc = float(ligne.split()[-1])
175      if "deadline" in ligne:
176        bloc.date_end = dt.datetime.strptime(
177          "{}".format(ligne.split()[-1]), "%Y-%m-%d"
178        )
179        bloc.date_end = dt.date(
180          bloc.date_end.year,
181          bloc.date_end.month,
182          bloc.date_end.day,
183        )
184        bloc.line_end = num + 1
185        if bloc.name == project:
186          blocs.append(bloc)
187
188  if mode_conso:
189    for bloc in blocs:
190      bloc.consos = set()
191      with open(filename, "r") as filein:
192        for _ in xrange(bloc.line_beg - 1):
193          next(filein)
194        for num, ligne in enumerate(filein):
195          if num > bloc.line_end - bloc.line_beg:
196            break
197          if len(ligne.split()) == 2 and \
198             ligne.split()[0] != "Allocated":
199            login, conso = ligne.lower().split()
200            conso = float(conso)
201            # bloc["consos"].add((login.lower(), conso))
202            bloc.consos.add(
203              ConsoItem(
204                login.lower(),
205                bloc.cpt_date,
206                conso,
207              )
208            )
209
210  return blocs[0].cpt_date, blocs
211
212
213#######################################################################
214def parse_idris_cpt(filename, project):
215
216  import datetime as dt
217
218  print(filename)
219
220  blocs = []
221
222  with open(filename, "r") as filein:
223    # bloc = {}
224    bloc = ProjectBloc(
225      project,
226      "idris",
227    )
228    bloc.consos = set()
229    for num, ligne in enumerate(filein):
230      if "mise a jour" in ligne:
231        jour, heure = ligne.strip().split()[-2:]
232        bloc.cpt_date = dt.datetime.strptime(
233          "{} {}".format(jour, heure), "%d/%m/%Y %H:%M"
234        )
235        bloc.date_end = dt.date(bloc.cpt_date.year, 12, 31)
236        # bloc["date_end"] = dt.datetime.strptime(
237        #   "{} {}".format(jour, heure), "%d/%m/%Y %H:%M"
238        # )
239      elif "Comptabilite" in ligne:
240        bloc.machine = ligne.strip().split()[-1].strip(".")
241        bloc.node = "standard"
242      elif "Heures" in ligne:
243        bloc.alloc = int(ligne.strip().split()[-1])
244      elif "Totaux" in ligne:
245        conso = float(ligne.strip().split()[1])
246        # bloc.consos.add(("total", conso))
247        bloc.consos.add(
248          ConsoItem(
249            "total",
250            bloc.cpt_date,
251            conso,
252          )
253        )
254      elif project in ligne:
255        login = ligne.strip().split()[0]
256        try:
257          conso = float(ligne.strip().split()[2])
258        except ValueError:
259          conso = float("nan")
260        # bloc.consos.add((login, conso))
261        bloc.consos.add(
262          ConsoItem(
263            login.lower(),
264            bloc.cpt_date,
265            conso,
266          )
267        )
268
269    blocs.append(bloc)
270
271  return blocs[0].cpt_date, blocs
272
273
274#######################################################################
275def date_from_filename(filename):
276  """
277  """
278  return os.path.basename(filename).split("_")[-2]
279
280
281#######################################################################
282def find_input_files(data_dir, pattern, date_range):
283  """
284  """
285  file_list = glob.glob(os.path.join(data_dir, pattern))
286
287  if date_range:
288    res = []
289    for filename in file_list:
290      file_date = date_from_filename(filename)
291      if file_date >= min(date_range) and \
292         file_date <= max(date_range):
293        res.append(filename)
294  else:
295    res = file_list
296
297  # return set(res)
298  return sorted(res)
299
300
301#######################################################################
302if __name__ == "__main__":
303  pass
Note: See TracBrowser for help on using the repository browser.