Index: /TOOLS/ConsoGENCI/trunk/bin/db_data.py.init
===================================================================
--- /TOOLS/ConsoGENCI/trunk/bin/db_data.py.init	(revision 2775)
+++ /TOOLS/ConsoGENCI/trunk/bin/db_data.py.init	(revision 2775)
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# This must come first
+from __future__ import print_function, unicode_literals, division
+
+db_host = "xxx.xxx.xxx.xxx"
+db_port = "xxxx"
+db_name = "db_name"
+db_user = "db_user"
+db_pwd  = "db_pwd"
Index: /TOOLS/ConsoGENCI/trunk/bin/init_alloc_tbl.py
===================================================================
--- /TOOLS/ConsoGENCI/trunk/bin/init_alloc_tbl.py	(revision 2774)
+++ /TOOLS/ConsoGENCI/trunk/bin/init_alloc_tbl.py	(revision 2775)
@@ -1,4 +1,12 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
+
+# ==================================================================== #
+# Author: Sonia Labetoulle                                             #
+# Contact: sonia.labetoulle _at_ ipsl.jussieu.fr                       #
+# Created: 2016                                                        #
+# History:                                                             #
+# Modification:                                                        #
+# ==================================================================== #
 
 # ==================================================================== #
@@ -17,4 +25,5 @@
 # Application library imports
 import libconsodb as cdb
+import db_data
 
 
@@ -23,31 +32,4 @@
 
   project_list = [
-    {
-      "name": "gen0826",
-      "centre": "tgcc",
-      "machine": "curie",
-      "node": "fat/large",
-      "alloc": 114000,
-      "start": "2015-01-01 00:00:00",
-      "end": "2015-12-31 23:59:59",
-    },
-    {
-      "name": "gen0826",
-      "centre": "tgcc",
-      "machine": "curie",
-      "node": "hybrid",
-      "alloc": 25000,
-      "start": "2015-01-01 00:00:00",
-      "end": "2015-12-31 23:59:59",
-    },
-    {
-      "name": "gen0826",
-      "centre": "tgcc",
-      "machine": "curie",
-      "node": "thin/standard",
-      "alloc": 114000,
-      "start": "2015-01-01 00:00:00",
-      "end": "2015-12-31 23:59:59",
-    },
     {
       "name": "gencmip6",
@@ -104,14 +86,45 @@
       "end": "2016-12-31 23:59:59",
     },
+    {
+      "name": "gen0826",
+      "centre": "tgcc",
+      "machine": "curie",
+      "node": "fat/large",
+      "alloc": 114000,
+      "start": "2015-01-01 00:00:00",
+      "end": "2015-12-31 23:59:59",
+    },
+    {
+      "name": "gen0826",
+      "centre": "tgcc",
+      "machine": "curie",
+      "node": "hybrid",
+      "alloc": 25000,
+      "start": "2015-01-01 00:00:00",
+      "end": "2015-12-31 23:59:59",
+    },
+    {
+      "name": "gen0826",
+      "centre": "tgcc",
+      "machine": "curie",
+      "node": "thin/standard",
+      "alloc": 114000,
+      "start": "2015-01-01 00:00:00",
+      "end": "2015-12-31 23:59:59",
+    },
   ]
 
   # Connection info
-  db_host = "134.157.170.104"
-  # db_port = "5432"
-  db_name = "prodiguer"
-  db_user = "prodiguer_db_user"
-  # db_pwd = "secret"
+  # db_host = "134.157.170.104"
+  # # db_port = "5432"
+  # db_name = "prodiguer"
+  # db_user = "prodiguer_db_user"
+  # # db_pwd = "secret"
 
-  conn, cursor = cdb.connect_db(db_host, db_name, db_user)
+  conn, cursor = cdb.connect_db(
+    db_data.db_host,
+    db_data.db_name,
+    db_data.db_user
+  )
 
   # Build request
Index: /TOOLS/ConsoGENCI/trunk/bin/init_conso_tbl.py
===================================================================
--- /TOOLS/ConsoGENCI/trunk/bin/init_conso_tbl.py	(revision 2774)
+++ /TOOLS/ConsoGENCI/trunk/bin/init_conso_tbl.py	(revision 2775)
@@ -1,4 +1,12 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
+
+# ==================================================================== #
+# Author: Sonia Labetoulle                                             #
+# Contact: sonia.labetoulle _at_ ipsl.jussieu.fr                       #
+# Created: 2016                                                        #
+# History:                                                             #
+# Modification:                                                        #
+# ==================================================================== #
 
 # This must come first
@@ -15,4 +23,5 @@
 import libconso_db as cdb
 import libconso_cpt as ccpt
+import db_data
 
 pp = pprint.PrettyPrinter(indent=2)
@@ -78,10 +87,14 @@
   if args.verbose:
     print("Connection to database")
-  db_host = "134.157.170.104"
-  # db_port = "5432"
-  db_name = "prodiguer"
-  db_user = "prodiguer_db_user"
-  # db_pwd = "secret"
-  conn, cursor = cdb.connect_db(db_host, db_name, db_user)
+  # db_host = "134.157.170.104"
+  # # db_port = "5432"
+  # db_name = "prodiguer"
+  # db_user = "prodiguer_db_user"
+  # # db_pwd = "secret"
+  conn, cursor = cdb.connect_db(
+    db_data.db_host,
+    db_data.db_name,
+    db_data.db_user
+  )
 
   # .. Extract allocation id from table ..
Index: /TOOLS/ConsoGENCI/trunk/bin/insert_conso_tbl.py
===================================================================
--- /TOOLS/ConsoGENCI/trunk/bin/insert_conso_tbl.py	(revision 2775)
+++ /TOOLS/ConsoGENCI/trunk/bin/insert_conso_tbl.py	(revision 2775)
@@ -0,0 +1,217 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# ==================================================================== #
+# Author: Sonia Labetoulle                                             #
+# Contact: sonia.labetoulle _at_ ipsl.jussieu.fr                       #
+# Created: 2016                                                        #
+# History:                                                             #
+# Modification:                                                        #
+# ==================================================================== #
+
+# This must come first
+from __future__ import print_function, unicode_literals, division
+
+# Standard library imports
+import os
+import math
+# import datetime as dt
+from argparse import ArgumentParser
+import shutil
+import pprint
+
+# Application library imports
+import libconso_db as cdb
+import libconso_cpt as ccpt
+import db_data
+
+pp = pprint.PrettyPrinter(indent=2)
+
+
+#######################################################################
+def get_arguments():
+  parser = ArgumentParser()
+  parser.add_argument("project", action="store",
+                      help="Project name")
+  parser.add_argument("center", action="store",
+                      help="Center name (idris/tgcc)")
+
+  parser.add_argument("-v", "--verbose", action="store_true",
+                      help="verbose mode")
+  parser.add_argument("-d", "--dryrun", action="store_true",
+                      help="only print what is to be done")
+  parser.add_argument("-r", "--range", action="store", nargs=2,
+                      help="date range: ssaammjj ssaammjj")
+
+  # parser.add_argument("-f", "--full", action="store_true",
+  #                     help="plot the whole period")
+  # parser.add_argument("-i", "--increment", action="store",
+  #                     type=int, default=1, dest="inc",
+  #                     help="sampling increment")
+  # parser.add_argument("-m", "--max", action="store_true",
+  #                     help="plot with y_max = allocation")
+  # parser.add_argument("-s", "--show", action="store_true",
+  #                     help="interactive mode")
+  # parser.add_argument("-d", "--dods", action="store_true",
+  #                     help="copy output on dods")
+
+  return parser.parse_args()
+
+
+#######################################################################
+if __name__ == "__main__":
+
+  # .. Initialization ..
+  # ====================
+  # ... Command line arguments ...
+  # ------------------------------
+  args = get_arguments()
+  if args.verbose:
+    print(args)
+
+  # ... Files and directories ...
+  # -----------------------------
+  ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+  DATA_DIR = os.path.join(ROOT_DIR, "data")
+  SUBMIT_DIR = os.getcwd()
+
+  pattern = ccpt.cpt_pattern(center=args.center, project=args.project)
+  dirin = os.path.join(DATA_DIR, args.center, "tmp")
+  dirout = os.path.join(DATA_DIR, args.center, args.project)
+  filelist = ccpt.find_input_files(dirin, pattern, args.range)
+
+  if not filelist:
+    print("No files found, exit")
+    exit(0)
+
+  if args.verbose:
+    print("SUBMIT_DIR:", SUBMIT_DIR)
+    print("DATA_DIR:", DATA_DIR)
+    print("dirin:", dirin)
+
+  # .. Connection to database ..
+  # ============================
+  if args.verbose:
+    print("Connection to database")
+  # db_host = "134.157.170.104"
+  # # db_port = "5432"
+  # db_name = "prodiguer"
+  # db_user = "prodiguer_db_user"
+  # # db_pwd = "secret"
+  conn, cursor = cdb.connect_db(
+    db_data.db_host,
+    db_data.db_name,
+    db_data.db_user
+  )
+
+  # .. Extract allocation id from table ..
+  # ======================================
+  table_name = "conso.tbl_allocation"
+  request = (
+    # "SELECT id "
+    "SELECT * "
+    "FROM " + table_name + " "
+    "WHERE project = '" + args.project + "'"
+    "  AND centre = '" + args.center + "'"
+    # "  AND start_date < '" + dt.datetime.strftime(date, "%Y-%m-%d") + "'"
+    # "  AND end_date > '" + dt.datetime.strftime(date, "%Y-%m-%d") + "'"
+    "ORDER BY start_date"
+    ";"
+  )
+
+  cdb.select_db(cursor, request)
+  # print(cursor.rowcount)
+  # print(cursor.fetchall())
+
+  allocs = []
+  for row in cursor:
+    allocs.append(ccpt.AllocRow(row))
+
+  # .. Build dictionary from files ..
+  # =================================
+  for filename in filelist:
+    conso_per_alloc = {}
+
+    date, blocs = ccpt.parse_input_cpt(
+      filename, args.project, args.center, mode_conso=True
+    )
+
+    for bloc in blocs:
+      if not bloc.alloc_id:
+        bloc.alloc_id = ccpt.get_project_id(bloc, allocs)
+        if not bloc.alloc_id:
+          print("no alloc id found, skip bloc")
+          print(bloc.machine, bloc.node, bloc.cpt_date)
+          pp.pprint(allocs)
+          continue
+      if bloc.alloc_id not in conso_per_alloc:
+        conso_per_alloc[bloc.alloc_id] = set()
+      for conso in bloc.consos:
+        conso_per_alloc[bloc.alloc_id].add(conso)
+
+    # .. Insert data in table, one alloc_id at a time ..
+    # ==================================================
+    for alloc_id, consos in conso_per_alloc.iteritems():
+      # ... Create request sub string ...
+      # ---------------------------------
+      lines_req = [
+        (
+          "('{alloc}', "
+          "'{date}', "
+          "{total_hrs}, "
+          "{login}, "
+          "{create})"
+        ) .format(
+          alloc=alloc_id,
+          date=item.date,
+          total_hrs=item.conso if not math.isnan(item.conso) else "'NaN'",
+          login="'"+item.login+"'" if item.login != "total" else "NULL",
+          create="CURRENT_TIMESTAMP",
+        ) for item in consos
+      ]
+
+      # ... Create full request ...
+      # ---------------------------
+      table_name = "conso.tbl_consumption"
+      request = (
+        "INSERT INTO " + table_name + " ("
+        "  allocation_id, "
+        "  date, "
+        "  total_hrs, "
+        "  login, "
+        "  row_create_date "
+        ") "
+        "VALUES "
+      )
+      request = request + ", ".join(lines_req)
+
+      # ... Execute request ...
+      # -----------------------
+      if args.verbose:
+        print("Execute request for alloc_id = {}".format(alloc_id))
+        print(request)
+      cdb.insert_db(cursor, request)
+
+      # ... Commit inserts ...
+      # ----------------------
+      if not args.dryrun:
+        if args.verbose:
+          print("Commit inserts")
+        cdb.commit_db(conn)
+
+    # .. Move processed file to project directory ..
+    # ===============================================
+    if args.verbose:
+      print("Move processed file:")
+      print("{} => {}".format(filename, dirout))
+    if not args.dryrun:
+      try:
+        shutil.move(filename, dirout)
+      except Exception as rc:
+        print("Could not move {}:\n{}".format(filename, rc))
+
+  # .. Close connection to database ..
+  # ==================================
+  if args.verbose:
+    print("Close connection")
+  cdb.close_db(conn)
Index: /TOOLS/ConsoGENCI/trunk/bin/libconso.py
===================================================================
--- /TOOLS/ConsoGENCI/trunk/bin/libconso.py	(revision 2774)
+++ /TOOLS/ConsoGENCI/trunk/bin/libconso.py	(revision 2775)
@@ -1,4 +1,12 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
+
+# ==================================================================== #
+# Author: Sonia Labetoulle                                             #
+# Contact: sonia.labetoulle _at_ ipsl.jussieu.fr                       #
+# Created: 2016                                                        #
+# History:                                                             #
+# Modification:                                                        #
+# ==================================================================== #
 
 # this must come first
@@ -13,5 +21,5 @@
 import subprocess
 import datetime as dt
-# import numpy as np
+import numpy as np
 import ConfigParser as cp
 
@@ -19,22 +27,32 @@
 
 
-########################################
-def dods_cp(filein, DIR):
-  """
-  """
-  if not DIR["DODS"]:
+########################################################################
+def dods_cp(img_out, img_name, DODS):
+  """
+  """
+  if not DODS["DIR"]:
     print("DODS directory not defined")
     return
 
-  basefile = os.path.basename(filein)
-
-  fileout = os.path.join(DIR["DODS"], basefile)
-  filepng = os.path.join(DIR["DODS"], "img", basefile.split(".")[0] + ".png")
-
-  #Â Copy file
-  shutil.copy(filein, fileout)
-
-  # Convert it to png for web page
-  command = ["convert", "-density", "200", fileout, filepng]
+  # .. Copy pdf file to dods server ..
+  # ==================================
+  command = [
+    "scp",
+    img_out,
+    "{}@{}:{}".format(
+      DODS["USER"],
+      DODS["SERVER"],
+      os.path.join(DODS["DIR"], "pdf", img_name + ".pdf")
+    )
+  ]
+  try :
+    subprocess.call(command)
+  except Exception as rc :
+    print("Error in scp for {}:\n{}".format(command, rc))
+
+  # .. Convert pdf to temporary png ..
+  # ==================================
+  img_png = img_out.replace(".pdf", ".png")
+  command = ["convert", "-density", "200", img_out, img_png]
 
   try :
@@ -43,12 +61,49 @@
     print("Error in convert for {}:\n{}".format(fileout, rc))
 
+  # .. Copy png file to dods server ..
+  # ==================================
+  command = [
+    "scp",
+    img_png,
+    "{}@{}:{}".format(
+      DODS["USER"],
+      DODS["SERVER"],
+      os.path.join(DODS["DIR"], "img", img_name + ".png")
+    )
+  ]
+  try :
+    subprocess.call(command)
+  except Exception as rc :
+    print("Error in scp for {}:\n{}".format(command, rc))
+
+  # .. Delete temporary png file ..
+  # ===============================
+
   return
 
-
-########################################
+  basefile = os.path.basename(filein)
+
+  fileout = os.path.join(DIR["DODS"], basefile)
+  filepng = os.path.join(DIR["DODS"], "img", basefile.split(".")[0] + ".png")
+
+  #Â Copy file
+  shutil.copy(filein, fileout)
+
+  # Convert it to png for web page
+  command = ["convert", "-density", "200", fileout, filepng]
+
+  try :
+    subprocess.call(command)
+  except Exception as rc :
+    print("Error in convert for {}:\n{}".format(fileout, rc))
+
+  return
+
+
+########################################################################
 def parse_config(filename):
 
   DIR = {}
-  OUT = {}
+  DODS = {}
 
   config = cp.ConfigParser(allow_no_value=True)
@@ -56,17 +111,17 @@
   config.read(filename)
 
-  for section in ("projet", "directories", "files"):
+  for section in ("projet", "directories"):
     if not config.has_section(section):
       print("Missing section {} in {}, we stop".format(section, filename))
       exit(1)
 
-  # ..Â Project name ..
-  # ------------------
+  # ...Â Project name ...
+  # --------------------
   section = "projet"
   option  = "name"
   project_name = config.get(section, option)
 
-  # ..Common directories ..
-  # -----------------------
+  # ... Common directories ...
+  # --------------------------
   section = "directories"
   for option in config.options(section):
@@ -80,14 +135,14 @@
         print("Could not create {}:\n{}".format(DIR[option], rc))
 
-  # ..Common files ..
-  # -----------------
-  section = "files"
+  # .. DODS configuration ...
+  # -------------------------
+  section = "dods"
   for option in config.options(section):
-    OUT[option] = config.get(section, option)
-
-  return (project_name, DIR, OUT)
-
-
-########################################
+    DODS[option] = config.get(section, option)
+
+  return (DIR, DODS)
+
+
+########################################################################
 def string_to_percent(x):
   """
@@ -96,5 +151,5 @@
 
 
-########################################
+########################################################################
 def string_to_size_unit(x):
   """
@@ -108,5 +163,5 @@
 
 
-########################################
+########################################################################
 def string_to_float(x):
   """
@@ -115,12 +170,22 @@
 
 
-########################################
-def string_to_date(ssaammjj, fmt="%Y-%m-%d"):
-  """
-  """
-  return dt.datetime.strptime(ssaammjj, fmt)
-
-
-########################################
+########################################################################
+def string_to_date(ssaammjj, fmt="%Y%m%d"):
+  """
+  """
+  fmts = ["%Y%m%d", "%Y-%m-%d", "%Y_%m_%d"]
+
+  for fmt in fmts:
+    try:
+      res = dt.datetime.strptime(ssaammjj, fmt)
+    except Exception as rc:
+      pass
+    else:
+      break 
+
+  return res.date()
+
+
+########################################################################
 def string_to_datetime(string, fmt="%Y-%m-%d-%H:%M"):
   """
@@ -129,5 +194,5 @@
 
 
-# ########################################
+# ########################################################################
 # def date_to_string(dtdate, fmt="%Y-%m-%d"):
 #   """
@@ -136,5 +201,5 @@
 
 
-########################################
+########################################################################
 def where_we_run():
 
@@ -150,5 +215,5 @@
 
 
-########################################
+########################################################################
 def get_last_file(dir_data, pattern):
   """
@@ -166,5 +231,5 @@
 
 
-########################################
+########################################################################
 def get_input_files(dir_data, file_list):
   """
@@ -184,6 +249,6 @@
 
 
-########################################
-def plot_save(img_in, img_out, title):
+########################################################################
+def plot_save(img_out, title):
   """
   """
@@ -192,9 +257,17 @@
   dpi = 200.
 
-  print(img_in)
-  with PdfPages(img_in) as pdf:
+  dirname = os.path.dirname(img_out)
+  if not os.path.isdir(dirname):
+    print("mkdir {}".format(dirname))
+    try :
+      os.makedirs(dirname)
+    except Exception as rc :
+      print("Could not create {}:\n{}".format(dirname, rc))
+
+  with PdfPages(img_out) as pdf:
     pdf.savefig(dpi=dpi)
 
-    # pdf file's metadata
+    # ... pdf file's metadata ...
+    # ---------------------------
     d = pdf.infodict()
     d["Title"]   = title
@@ -206,48 +279,163 @@
     # d["ModDate"] = dt.datetime.today()
 
-  # if os.path.isdir(DIR["SAVEPLOT"]):
-  #   # img_out = os.path.join(DIR["SAVEPLOT"],
-  #   #                        "{}_{}.pdf".format(img_name, suffix))
-  #   shutil.copy(img_in, img_out)
-
-
-########################################
-class Project(object):
-
-  #---------------------------------------
-  def __init__(self, project_name):
-    self.project = project_name
-
-  #---------------------------------------
-  def fill_data(self, row):
-    # import json
-    # dico = json.load(open(filein, "r"))
-    # self.deadline = string_to_date(dico["deadline"]) + \
-    #                 dt.timedelta(days=-1)
-    # self.alloc = dico["alloc"]
-    self.id = row["id"]
-    self.centre = row["centre"]
-    self.machine = row["machine"]
-    self.node = row["node_type"]
-    self.start_date = row["start_date"]
-    self.end_date = row["end_date"]
-    self.alloc = row["total_hrs"]
+
+########################################################################
+class AllocItem(object):
+
+  #---------------------------------------------------------------------
+  def __init__(
+    self,
+    alloc_id,
+    machine,
+    node_type,
+    start_date,
+    end_date,
+    alloc
+  ):
+
+    self.alloc_id   = alloc_id
+    self.machine    = machine
+    self.node_type  = node_type
+    self.start_date = start_date
+    self.end_date   = end_date
+    self.alloc      = alloc
 
     delta = self.end_date - self.start_date
     self.days = delta.days + 1
 
-
-########################################
+    self.daily_conso = self.alloc / self.days 
+
+  #---------------------------------------------------------------------
+  def __repr__(self):
+    return "{} ({:%Y%m%d}/{:%Y%m%d}): {}".format(
+      self.machine,
+      self.start_date,
+      self.end_date,
+      self.alloc,
+    )
+
+
+########################################################################
+class Project(object):
+
+  #---------------------------------------------------------------------
+  def __init__(self, project_name, center):
+    self.project = project_name
+    self.centre = center
+    self.alloc_items = []
+
+  #---------------------------------------------------------------------
+  def __repr__(self):
+    return "{}/{}: {}".format(
+      self.project,
+      self.centre,
+      self.alloc_items,
+    )
+
+  #---------------------------------------------------------------------
+  def add_alloc(
+    self,
+    alloc_id,
+    machine,
+    node_type,
+    start_date,
+    end_date,
+    alloc
+  ):
+
+    alloc_item = AllocItem(
+      alloc_id,
+      machine,
+      node_type,
+      start_date,
+      end_date,
+      alloc
+    )
+
+    self.alloc_items.append(alloc_item)
+
+    self.start_date = min(
+      [item.start_date for item in self.alloc_items]
+    )
+    self.end_date = max(
+      [item.end_date for item in self.alloc_items]
+    )
+
+    self.alloc = sum(
+      [item.alloc for item in self.alloc_items]
+    )
+    self.max_daily_conso = max(
+      [item.daily_conso for item in self.alloc_items]
+    )
+
+
+    self.days = sum(
+      [item.days for item in self.alloc_items]
+    )
+
+    self.nb_alloc = len(self.alloc_items)
+
+  #---------------------------------------------------------------------
+  def get_theo_eq(self, dates):
+
+    x0 = 0
+    y0 = 0.
+
+    for item in self.alloc_items:
+      yi = y0
+      yf = y0 + item.alloc / self.alloc
+      
+      if item.start_date.date() in dates:
+        xi = dates.index(item.start_date.date())
+      else:
+        xi = 0
+
+      if item.end_date.date() in dates:
+        xf = dates.index(item.end_date.date())
+      else:
+        xf = len(dates) + 1
+
+      m = np.array([[xi, 1.], [xf+1, 1.]])
+      n = np.array([yi, yf])
+
+      try:
+        polynome = np.poly1d(np.linalg.solve(m, n))
+      except np.linalg.linalg.LinAlgError:
+        print("error poly")
+        item.theo_eq = None
+      else:
+        item.theo_eq = polynome
+        item.xi = xi
+        item.xf = xf
+        item.yi = yi
+        item.yf = yf
+      
+      y0 = yf
+
+  #---------------------------------------------------------------------
+  def fill_data(self, row):
+    # self.id = row["id"]
+    # self.machine = row["machine"]
+    # self.node = row["node_type"]
+    # self.start_date = row["start_date"]
+    # self.end_date = row["end_date"]
+    # self.alloc = row["total_hrs"]
+
+    delta = self.end_date - self.start_date
+    self.days = delta.days + 1
+
+
+########################################################################
 class SizeUnit(object):
-  #---------------------------------------
+  #---------------------------------------------------------------------
   def __init__(self, size, unit):
     self.size = size
     self.unit = unit
 
-  #---------------------------------------
+  #---------------------------------------------------------------------
   def __repr__(self):
     return "{:6.2f}{}o".format(self.size, self.unit)
 
-  #---------------------------------------
+  #---------------------------------------------------------------------
   def convert_size(self, unit_out):
     """
@@ -271,5 +459,5 @@
 
 
-########################################
+########################################################################
 if __name__ == '__main__':
   pass
Index: /TOOLS/ConsoGENCI/trunk/bin/libconso_cpt.py
===================================================================
--- /TOOLS/ConsoGENCI/trunk/bin/libconso_cpt.py	(revision 2774)
+++ /TOOLS/ConsoGENCI/trunk/bin/libconso_cpt.py	(revision 2775)
@@ -1,4 +1,12 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
+
+# ==================================================================== #
+# Author: Sonia Labetoulle                                             #
+# Contact: sonia.labetoulle _at_ ipsl.jussieu.fr                       #
+# Created: 2016                                                        #
+# History:                                                             #
+# Modification:                                                        #
+# ==================================================================== #
 
 # =================================================================== #
@@ -128,5 +136,5 @@
 def cpt_pattern(project, center):
 
-  return "cpt_{}_{}_*.dat".format(project, center)
+  return "cpt_{}_{}_*.dat".format(center, project)
 
 
@@ -289,5 +297,6 @@
     res = file_list
 
-  return set(res)
+  # return set(res)
+  return sorted(res)
 
 
Index: /TOOLS/ConsoGENCI/trunk/bin/libconso_db.py
===================================================================
--- /TOOLS/ConsoGENCI/trunk/bin/libconso_db.py	(revision 2774)
+++ /TOOLS/ConsoGENCI/trunk/bin/libconso_db.py	(revision 2775)
@@ -1,4 +1,12 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
+
+# ==================================================================== #
+# Author: Sonia Labetoulle                                             #
+# Contact: sonia.labetoulle _at_ ipsl.jussieu.fr                       #
+# Created: 2016                                                        #
+# History:                                                             #
+# Modification:                                                        #
+# ==================================================================== #
 
 # =================================================================== #
Index: OLS/ConsoGENCI/trunk/bin/libconsodb.py
===================================================================
--- /TOOLS/ConsoGENCI/trunk/bin/libconsodb.py	(revision 2774)
+++ 	(revision )
@@ -1,241 +1,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# ==================================================================== #
-# ssh readonly@prodiguer-test-db.ipsl.upmc.fr                          #
-# psql -U prodiguer_db_user prodiguer                                  #
-# ==================================================================== #
-
-
-# This must come first
-from __future__ import print_function, unicode_literals, division
-
-# Standard library imports
-import os
-import glob
-import psycopg2
-import psycopg2.extras
-
-# Application library imports
-
-
-########################################
-def connect_db(db_host, db_name, db_user):
-
-  conn_string = "host={} dbname={} user={}".format(
-    db_host, db_name, db_user
-  )
-
-  # Print the connection string we will use to connect
-  print("Connecting to database\n  -> {}".format(conn_string))
-
-  # Get a connection, if a connect cannot be made an exception will be
-  # raised here
-  try :
-    conn = psycopg2.connect(conn_string)
-  except Exception as rc:
-    print("Problem with DB connect:\n{}".format(rc))
-    exit(1)
-
-  # conn.cursor will return a cursor object, you can use this cursor
-  # to perform queries
-  # cursor = conn.cursor()
-  cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
-  print("Connected!\n")
-
-  return conn, cursor
-
-
-########################################
-def select_db(cursor, request):
-
-  # Execute query
-  try:
-    cursor.execute(request)
-  except Exception as rc:
-    print("Problem with select:\n{}".format(rc))
-    exit(1)
-
-  # # retrieve the records from the database
-  # records = cursor.fetchall()
-
-  # # print out the records using pretty print
-  # # note that the NAMES of the columns are not shown, instead just indexes.
-  # # for most people this isn't very useful so we'll show you how to return
-  # # columns as a dictionary (hash) in the next example.
-  # pprint(records)
-
-
-########################################
-def insert_db(cursor, request):
-  """
-  """
-
-  # Execute query
-  try:
-    cursor.execute(request)
-  except Exception as rc:
-    print("Problem with insert:\n{}".format(rc))
-    exit(1)
-
-
-########################################
-def commit_db(conn):
-  """
-  """
-
-  # Execute query
-  try:
-    conn.commit()
-  except Exception as rc:
-    print("Problem with commit:\n{}".format(rc))
-    exit(1)
-
-
-########################################
-def parse_input_cpt(filename, project, center):
-
-  if center == "idris":
-    return parse_idris_cpt(filename, project)
-  elif center == "tgcc":
-    return parse_tgcc_cpt(filename, project)
-  else:
-    print("Unknown center {}".format(center))
-    exit()
-
-
-########################################
-def parse_tgcc_cpt(filename, project):
-
-  import datetime as dt
-
-  consos = set()
-
-  with open(filename, "r") as filein:
-    # Skip lines until we find project name.
-    # Then extract script date
-    for ligne in filein:
-      if project["name"] in ligne:
-        date = ligne.split()[-1]
-        date = dt.datetime.strptime(
-          "{} {}".format(date), "%d-%m-%Y"
-        )
-        project["machine"] = ligne.split()[5]
-        project["nodes"]   = ligne.split()[6]
-        break
-
-    # Skip next two lines : first is blank and second is login titles
-    for _ in xrange(1):
-      next(filein)
-
-    # Login list, until blank line
-    for ligne in filein:
-      if not ligne.strip():
-        break
-      login, conso = ligne.split()
-      # logins[login] = float(conso)
-      try:
-        conso = float(conso)
-      except ValueError:
-        conso = float("nan")
-      consos.add((login, conso))
-
-    # Skip until we find consumed time (hours)
-    for ligne in filein:
-      if "Total" in ligne:
-        total = float(ligne.split()[-1])
-        break
-
-    # Skip until we find allocated time (hours)
-    for ligne in filein:
-      if "Allocated" in ligne:
-        alloc = float(ligne.split()[-1])
-        break
-
-    # Skip until we find theoratical use (%)
-    for ligne in filein:
-      if "Suggested use at this time" in ligne:
-        utheo = float(ligne.split()[-1].strip("%"))
-        break
-
-    # Skip until we find real use (%)
-    for ligne in filein:
-      if "Real use at this time" in ligne:
-        ureal = float(ligne.split()[-1].strip("%"))
-        break
-
-    # Skip until we find deadline
-    for ligne in filein:
-      if "Project deadline" in ligne:
-        deadline = ligne.split()[-1]
-        break
-
-  # return project, logins, today, total, utheo, ureal
-  return date, alloc, consos
-
-
-########################################
-def parse_idris_cpt(filename, project):
-
-  import datetime as dt
-
-  # print(filename)
-
-  with open(filename, "r") as filein:
-    lignes = filein.readlines()
-
-  consos = set()
-
-  for ligne in lignes:
-    if "mise a jour" in ligne:
-      jour, heure = ligne.strip().split()[-2:]
-    elif "Heures" in ligne:
-      alloc = int(ligne.strip().split()[-1])
-    elif "Totaux" in ligne:
-      conso = float(ligne.strip().split()[1])
-      consos.add(("total", conso))
-    elif project in ligne:
-      login = ligne.strip().split()[0]
-      try:
-        conso = float(ligne.strip().split()[2])
-      except ValueError:
-        conso = float("nan")
-      consos.add((login, conso))
-
-  date = dt.datetime.strptime(
-    "{} {}".format(jour, heure), "%d/%m/%Y %H:%M"
-  )
-
-  # return jour, heure, alloc, consos
-  return date, alloc, consos
-
-
-########################################
-def find_input_files(data_dir, pattern, date_range):
-  """
-  """
-  # os.chdir(DATA_DIR)
-  # pattern = "compta_*.dat"
-  file_list = glob.glob(os.path.join(data_dir, pattern))
-  # if file_list:
-  #   res = sorted(file_list)
-  # else:
-  #   res = None
-  # os.chdir(SUBMIT_DIR)
-
-  if date_range:
-    res = []
-    for filename in file_list:
-      file_date = os.path.basename(filename).split("_")[1]
-      if file_date >= min(date_range) and \
-         file_date <= max(date_range):
-        res.append(filename)
-  else:
-    res = file_list
-
-  return set(res)
-
-
-########################################
-if __name__ == "__main__":
-  pass
Index: /TOOLS/ConsoGENCI/trunk/bin/plot_bilan.py
===================================================================
--- /TOOLS/ConsoGENCI/trunk/bin/plot_bilan.py	(revision 2774)
+++ /TOOLS/ConsoGENCI/trunk/bin/plot_bilan.py	(revision 2775)
@@ -1,4 +1,12 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
+
+# ==================================================================== #
+# Author: Sonia Labetoulle                                             #
+# Contact: sonia.labetoulle _at_ ipsl.jussieu.fr                       #
+# Created: 2016                                                        #
+# History:                                                             #
+# Modification:                                                        #
+# ==================================================================== #
 
 # this must come first
@@ -16,13 +24,25 @@
 from libconso import *
 import libconsodb as cdb
-
-
-########################################
+import db_data
+
+
+########################################################################
+class PlotData(object):
+  #---------------------------------------------------------------------
+  def __init__(self, date_min, date_max):
+    self.date_min = date_min
+    self.date_max = date_max
+
+    self.data = DataDict()
+    self.data.init_range(self.date_min, self.date_max)
+
+
+########################################################################
 class DataDict(dict):
-  #---------------------------------------
+  #---------------------------------------------------------------------
   def __init__(self):
     self = {}
 
-  #---------------------------------------
+  #---------------------------------------------------------------------
   def init_range(self, date_beg, date_end, inc=1):
     """
@@ -38,27 +58,40 @@
       self.add_item(date)
 
-  #---------------------------------------
+  #---------------------------------------------------------------------
   def fill_data(self, projet):
-  # def fill_data(self, filein):
-    """
-    """
+    """
+    """
+
+    id_condition = (
+      "({})".format(
+        " OR ".join(
+          [
+            "allocation_id={}".format(item.alloc_id)
+            for item in projet.alloc_items
+          ]
+        )
+      )
+    )
+
     table_name = "conso.tbl_consumption"
     request = (
-      "SELECT date, total_hrs "
+      "SELECT date, total_hrs, allocation_id "
       "FROM " + table_name + " "
-      "WHERE allocation_id = '" + str(projet.id) + "'"
-      "  AND login IS NULL "
+      "WHERE login IS NULL "
+      "  AND " + id_condition + " "
       "ORDER BY date"
       ";"
     )
+
+    if args.verbose:
+      print("Access table \"{}\"".format(table_name))
+      print(request)
     cdb.select_db(cursor, request)
 
-    for date, conso in cursor:
+    for date, conso, alloc_id in cursor:
       if date.date() in self:
-        # print(date.date(), conso)
-        # Days since start_date
         real_use = conso / projet.alloc
         self.add_item(
-          date=date,
+          date=date.date(),
           conso=conso,
           real_use=real_use,
@@ -66,40 +99,5 @@
         self[date.date()].fill()
 
-  #   try:
-  #     data = np.genfromtxt(
-  #       filein,
-  #       skip_header=1,
-  #       converters={
-  #         0: string_to_date,
-  #         1: string_to_float,
-  #         2: string_to_percent,
-  #         3: string_to_percent,
-  #         4: string_to_float,
-  #         5: string_to_float,
-  #         6: string_to_float,
-  #         7: string_to_float,
-  #       },
-  #       missing_values="nan",
-  #     )
-  #   except Exception as rc:
-  #     print("Empty file {}:\n{}".format(filein, rc))
-  #     exit(1)
-
-  #   for date, conso, real_use, theo_use, \
-  #       run_mean, pen_mean, run_std, pen_std in data:
-  #     if date in self:
-  #       self.add_item(
-  #         date,
-  #         conso,
-  #         real_use,
-  #         theo_use,
-  #         run_mean,
-  #         pen_mean,
-  #         run_std,
-  #         pen_std,
-  #       )
-  #       self[date].fill()
-
-  #---------------------------------------
+  #---------------------------------------------------------------------
   def add_item(self, date, conso=np.nan,
                real_use=np.nan, theo_use=np.nan,
@@ -108,5 +106,6 @@
     """
     """
-    self[date.date()] = Conso(
+    # self[date.date()] = Conso(
+    self[date] = Conso(
       date, conso,
       real_use, theo_use,
@@ -115,59 +114,20 @@
     )
 
-  #---------------------------------------
-  def theo_equation(self, projet):
-    """
-    """
-    (dates, theo_uses) = \
-      zip(*((item.date, item.theo_use)
-            for item in self.get_items_in_full_range()))
-
-    # (idx_min, idx_max) = \
-    #     (np.nanargmin(theo_uses), np.nanargmax(theo_uses))
-
-    # x1 = dates[idx_min].timetuple().tm_yday
-    # x2 = dates[idx_max].timetuple().tm_yday
-    x1 = projet.start_date.timetuple().tm_yday
-    x2 = projet.end_date.timetuple().tm_yday
-
-    # y1 = theo_uses[idx_min]
-    # y2 = theo_uses[idx_max]
-    y1 = 0
-    y2 = 1
-
-    m = np.array([[x1, 1.], [x2, 1.]], dtype="float")
-    n = np.array([y1, y2], dtype="float")
-
-    poly_ok = True
-    try:
-      poly_theo = np.poly1d(np.linalg.solve(m, n))
-    except np.linalg.linalg.LinAlgError:
-      poly_ok = False
-
-    if poly_ok:
-      delta = (dates[0] + relativedelta(months=2) - dates[0]).days
-
-      poly_delay = np.poly1d(
-        [poly_theo[1], poly_theo[0] - poly_theo[1] * delta]
-      )
-
-      self.poly_theo = poly_theo
-      self.poly_delay = poly_delay
-
-  #---------------------------------------
+  #---------------------------------------------------------------------
   def get_items_in_range(self, date_beg, date_end, inc=1):
     """
     """
     items = (item for item in self.itervalues()
-                   if item.date >= date_beg and
-                      item.date <= date_end)
+                   if item.date.date() >= date_beg and
+                      item.date.date() <= date_end)
     items = sorted(items, key=lambda item: item.date)
 
     return items[::inc]
 
-  #---------------------------------------
+  #---------------------------------------------------------------------
   def get_items_in_full_range(self, inc=1):
     """
     """
+
     items = (item for item in self.itervalues())
     items = sorted(items, key=lambda item: item.date)
@@ -175,5 +135,5 @@
     return items[::inc]
 
-  #---------------------------------------
+  #---------------------------------------------------------------------
   def get_items(self, inc=1):
     """
@@ -187,5 +147,5 @@
 
 class Conso(object):
-  #---------------------------------------
+  #---------------------------------------------------------------------
   def __init__(self, date, conso=np.nan,
                real_use=np.nan, theo_use=np.nan,
@@ -204,18 +164,18 @@
     self.filled   = False
 
-  #---------------------------------------
+  #---------------------------------------------------------------------
   def __repr__(self):
     return "{:.2f} ({:.2%})".format(self.conso, self.real_use)
 
-  #---------------------------------------
+  #---------------------------------------------------------------------
   def isfilled(self):
     return self.filled
 
-  #---------------------------------------
+  #---------------------------------------------------------------------
   def fill(self):
     self.filled = True
 
 
-########################################
+########################################################################
 def plot_init():
   paper_size  = np.array([29.7, 21.0])
@@ -226,8 +186,10 @@
 
 
-########################################
-def plot_data(ax_conso, ax_theo, xcoord, dates,
-              consos, theo_uses, real_uses, theo_equs, theo_delay,
-              run_mean, pen_mean, run_std, pen_std):
+########################################################################
+def plot_data(
+  ax_conso, ax_theo, xcoord, dates,
+  consos, real_uses, theo_uses, delay_uses,
+  run_mean, pen_mean, run_std, pen_std
+):
   """
   """
@@ -249,17 +211,14 @@
     label="conso\nrÃ©elle (%)"
   )
+
   ax_theo.plot(
-    xcoord, theo_equs, "--",
+    xcoord, theo_uses, "--",
     color="firebrick", linewidth=0.5,
-    solid_capstyle="round", solid_joinstyle="round"
-  )
-  ax_theo.plot(
-    xcoord, theo_uses, line_style,
-    color="firebrick", linewidth=1, markersize=8,
     solid_capstyle="round", solid_joinstyle="round",
     label="conso\nthÃ©orique (%)"
   )
+
   ax_theo.plot(
-    xcoord, theo_delay, ":",
+    xcoord, delay_uses, ":",
     color="firebrick", linewidth=0.5,
     solid_capstyle="round", solid_joinstyle="round",
@@ -267,8 +226,10 @@
   )
 
-
-########################################
-def plot_config(fig, ax_conso, ax_theo, xcoord, dates, title,
-                conso_per_day, conso_per_day_2):
+########################################################################
+def plot_config(
+  fig, ax_conso, ax_theo,
+  xcoord, dates, max_real_use,
+  title, projet
+):
   """
   """
@@ -282,5 +243,5 @@
     ymax = conso_max  # + conso_max*.1
   else:
-    ymax = 3. * max(conso_per_day, conso_per_day_2)
+    ymax = 3. * projet.max_daily_conso
 
   if conso_max > ymax:
@@ -307,5 +268,31 @@
   ax_theo.set_ylim(0., 100)
 
-  # 2) Ticks labels
+  # 2) Plot ideal daily consumption in hours
+  #    Plot last real use value
+  x_list = []
+  y_list = []
+  conso_yticks = list(ax_conso.get_yticks())
+  for item in projet.alloc_items:
+    x_list.extend([item.xi, item.xf])
+    y_list.extend([item.daily_conso, item.daily_conso])
+    conso_yticks.append(item.daily_conso)
+  line_alpha = 0.5
+  line_label = "conso journaliÃšre\nidÃ©ale (heures)"
+  ax_conso.plot(
+    x_list, y_list,
+    color="blue", alpha=line_alpha,
+    label=line_label,
+  )
+
+  theo_yticks = list(ax_theo.get_yticks())
+  theo_yticks.append(max_real_use)
+  ax_theo.axhline(
+    y=max_real_use,
+    linestyle=":", linewidth=0.5,
+    color="green", alpha=line_alpha,
+  )
+
+  
+  # 3) Ticks labels
   (date_beg, date_end) = (dates[0], dates[-1])
   date_fmt = "{:%d-%m}"
@@ -331,9 +318,7 @@
   # ax.yaxis.set_minor_locator(minor_locator)
 
-  yticks = list(ax_conso.get_yticks())
-  yticks.append(conso_per_day)
-  if conso_per_day_2:
-    yticks.append(conso_per_day_2)
-  ax_conso.set_yticks(yticks)
+  ax_conso.set_yticks(conso_yticks)
+
+  ax_theo.set_yticks(theo_yticks)
 
   ax_theo.spines["right"].set_color("firebrick")
@@ -341,17 +326,13 @@
   ax_theo.yaxis.label.set_color("firebrick")
 
-  ax_conso.axhline(y=conso_per_day, color="blue", alpha=0.5,
-                   label="conso journaliÃšre\nidÃ©ale (heures)")
-
-  if conso_per_day_2:
-    ax_conso.axhline(y=conso_per_day_2, color="blue", alpha=0.5)
-
   for x, d in zip(xcoord, dates):
     # if d.weekday() == 0 and d.hour == 0:
     if d.weekday() == 0:
-      ax_conso.axvline(x=x, color="black", alpha=0.5,
-                       linewidth=0.5, linestyle=":")
-
-  # 3) Define axes title
+      ax_conso.axvline(
+        x=x, color="black", alpha=0.5,
+        linewidth=0.5, linestyle=":"
+      )
+
+  # 4) Define axes title
   for ax, label in (
     (ax_conso, "heures"),
@@ -361,10 +342,10 @@
     ax.tick_params(axis="y", labelsize="small")
 
-  # 4) Define plot size
+  # 5) Define plot size
   fig.subplots_adjust(
     left=0.08,
     bottom=0.09,
     right=0.93,
-    top=0.93,
+    top=0.92,
   )
 
@@ -378,6 +359,20 @@
     ax.legend(loc=loc, fontsize="x-small", frameon=False)
 
-
-########################################
+  alloc_label = (
+    "Allocation(s):\n" +
+    "\n".join([
+      "{:%d-%m-%Y}-{:%d-%m-%Y} : {:8,.0f}h".format(
+        item.start_date, item.end_date, item.alloc
+      ) for item in projet.alloc_items
+    ])
+  )
+  plt.figtext(
+    x=0.92, y=0.93, s=alloc_label,
+    backgroundcolor="linen",
+    ha="right", va="bottom", fontsize="x-small"
+  )
+
+
+########################################################################
 def get_arguments():
   parser = ArgumentParser()
@@ -407,5 +402,5 @@
 
 
-########################################
+########################################################################
 if __name__ == '__main__':
 
@@ -416,4 +411,7 @@
   args = get_arguments()
 
+  print(os.getcwd())
+  print(os.path.abspath(__file__))
+
   # ... Turn interactive mode off ...
   # ---------------------------------
@@ -428,7 +426,20 @@
     plt.ioff()
 
-  # # ... Files and directories ...
-  # # -----------------------------
-  # project_name, DIR, OUT = parse_config("bin/config.ini")
+  # ... Variables and constants ...
+  # -------------------------------
+  delay = 60  # 2 months delay
+
+  # ... Files and directories ...
+  # -----------------------------
+  config_file = os.path.join(
+    "card",
+    "config_{}_{}.ini".format(args.center, args.project)
+  )
+
+  if not os.path.isfile(config_file):
+    print("File {} missing ".format(config_file))
+    exit(1)
+
+  (DIR, DODS) = parse_config(config_file)
 
   # (file_param, file_utheo, file_data) = \
@@ -436,30 +447,53 @@
   #                     [OUT["PARAM"], OUT["UTHEO"], OUT["BILAN"]])
 
-  img_name = os.path.splitext(
-               os.path.basename(__file__)
-             )[0].replace("plot_", "")
-
-  # project_name = "rgzi"
-
-  # Connection info
-  db_host = "134.157.170.104"
-  # db_port = "5432"
-  db_name = "prodiguer"
-  db_user = "prodiguer_db_user"
-  # db_pwd = "secret"
-
-  conn, cursor = cdb.connect_db(db_host, db_name, db_user)
+  img_name = "{}_{}_{}".format(
+    os.path.splitext(
+      os.path.basename(__file__)
+    )[0].replace("plot_", ""),
+    args.project,
+    args.center,
+  )
+
+  # if args.verbose:
+  #   print("Save plot as >{}<".format(img_name))
+
+  conn, cursor = cdb.connect_db(
+    db_data.db_host,
+    db_data.db_name,
+    db_data.db_user
+  )
 
   # today = os.path.basename(file_param).strip(OUT["PARAM"])
-  today = dt.date.strftime(dt.date.today(), "%Y%m%d")
-
-  # if args.verbose:
-  #   fmt_str = "{:10s} : {}"
-  #   print(fmt_str.format("args", args))
-  #   print(fmt_str.format("today", today))
+  # today = dt.date.strftime(dt.date.today(), "%Y%m%d")
+  today = dt.date.today()
+
+  if args.verbose:
+    fmt_str = "{:10s} : {}"
+    print(fmt_str.format("args", args))
+    print(fmt_str.format("today", today))
   #   print(fmt_str.format("file_param", file_param))
   #   print(fmt_str.format("file_utheo", file_utheo))
   #   print(fmt_str.format("file_data", file_data))
-  #   print(fmt_str.format("img_name", img_name))
+    print(fmt_str.format("img_name", img_name))
+    print("")
+
+  # .. Range of dates ..
+  # ====================
+  if args.full:
+    (date_min, date_max) = (
+      dt.date(today.year, 1, 1),
+      dt.date(today.year, 12, 31),
+    )
+  elif args.range:
+    (date_min, date_max) = (args.range)
+  else:
+    (date_min, date_max) = (
+      dt.date(today.year, 1, 1),
+      dt.date(today.year, 12, 31),
+    )
+  bilan_plot = PlotData(date_min, date_max)
+
+  # print(bilan_plot.__dict__)
+  # exit()
 
   # .. Get project info ..
@@ -473,5 +507,6 @@
     "SELECT * "
     "FROM " + table_name + " "
-    "WHERE project = '" + args.project + "'"
+    "WHERE project = '" + args.project + "' "
+    "ORDER BY start_date"
     ";"
   )
@@ -481,15 +516,22 @@
   # print(cursor.fetchall())
 
-  print(cursor.description)
+  projet = Project(args.project, args.center)
+  # print(cursor.description)
   for row in cursor:
-    projet = Project(args.project)
-    projet.fill_data(row)
-    # print(row["project"], type(row["project"]))
-    # print(row["centre"], type(row["centre"]))
-    # print(row["machine"], type(row["machine"]))
-    # print(row["node_type"], type(row["node_type"]))
-    # print(row["start_date"], type(row["start_date"]))
-    # print(row["end_date"], type(row["end_date"]))
-    # print(row["total_hrs"], type(row["total_hrs"]))
+    # if row["start_date"].year == today.year:
+    if (bilan_plot.date_min >= row["start_date"].date() and
+        bilan_plot.date_min <= row["end_date"].date()) or \
+       (bilan_plot.date_max >= row["start_date"].date() and
+        bilan_plot.date_max <= row["end_date"].date()) or \
+       (bilan_plot.date_min <= row["start_date"].date() and
+        bilan_plot.date_max >= row["end_date"].date()):
+      projet.add_alloc(
+        row["id"],
+        row["machine"],
+        row["node_type"],
+        row["start_date"],
+        row["end_date"],
+        row["total_hrs"],
+      )
 
   # .. Fill in data ..
@@ -497,64 +539,11 @@
   # ... Initialization ...
   # ----------------------
+
   bilan = DataDict()
-  bilan.init_range(projet.start_date, projet.end_date)
-
-  # ... Extract data from file ...
-  # ------------------------------
-  # table_name = "conso.tbl_consumption"
-  # request = (
-  #   "SELECT date, total_hrs "
-  #   "FROM " + table_name + " "
-  #   "WHERE allocation_id = '" + str(projet.id) + "'"
-  #   "  AND login IS NULL "
-  #   "ORDER BY date"
-  #   ";"
-  # )
-  # cdb.select_db(cursor, request)
-
+  bilan.init_range(projet.start_date.date(), projet.end_date.date())
+
+  # ... Extract data from table ...
+  # -------------------------------
   bilan.fill_data(projet)
-  # for item in bilan.iteritems():
-  #   print(item)
-  # exit()
-
-  # ... Compute theoratical use from known data  ...
-  # ------------------------------------------------
-  bilan.theo_equation(projet)
-
-  # print(cursor.description)
-  # # for row in cursor:
-  # #   print(row)
-
-  # consos = np.array([conso for date, conso in cursor])
-  # dates = [date for date, conso in cursor]
-
-  # people = ['Tom', 'Dick', 'Harry', 'Slim', 'Jim']
-  # x_pos = np.arange(len(people))
-  # performance = 3 + 10 * np.random.rand(len(people))
-
-  # # x_pos = np.arange(len(consos))
-  # print (len(x_pos), type(x_pos))
-  # # print (len(people), type(people))
-  # print (len(performance), type(performance))
-  # print (len(consos), type(consos))
-
-  # # plt.barh(x_pos, performance, align='center', alpha=0.4)
-
-  # x_pos = np.arange(len(consos))
-  # print (len(x_pos), type(x_pos))
-  # plt.bar(x_pos, consos, align='center', alpha=0.4)
-  # # plt.yticks(x_pos, dates)
-
-  # # plt.barh(x_pos, conso)
-  # # plt.yticks(x_pos, people)
-  # # plt.xlabel('Performance')
-  # # plt.title('How fast do you want to go today?')
-
-  # plt.show()
-
-
-
-
-
 
   # .. Extract data depending on C.L. arguments ..
@@ -569,5 +558,8 @@
     selected_items = bilan.get_items(args.inc)
 
-  print(selected_items)
+  last_filled_date = max([
+    item.date for item in selected_items
+    if item.filled
+  ])
 
   # .. Compute data to be plotted ..
@@ -577,4 +569,6 @@
   xcoord = np.linspace(1, nb_items, num=nb_items)
   dates = [item.date for item in selected_items]
+
+  projet.get_theo_eq(dates)
 
   cumul = np.array([item.conso for item in selected_items],
@@ -585,31 +579,21 @@
   consos = np.array(consos, dtype=float)
 
-  if projet.project == "gencmip6":
-    alloc1 = 5.e6
-    alloc2 = projet.alloc - alloc1
-    conso_per_day   = 2 * alloc1 / projet.days
-    conso_per_day_2 = 2 * alloc2 / projet.days
-  else:
-    conso_per_day = projet.alloc / projet.days
-    conso_per_day_2 = None
-
-  theo_uses = np.array(
-    [100.*item.theo_use for item in selected_items],
-    dtype=float
-  )
   real_uses = np.array(
     [100.*item.real_use for item in selected_items],
     dtype=float
   )
-  theo_equs = np.array(
-    [100. * bilan.poly_theo(date.timetuple().tm_yday)
-      for date in dates],
-    dtype=float
-  )
-  theo_delay = np.array(
-    [100. * bilan.poly_delay(date.timetuple().tm_yday)
-      for date in dates],
-    dtype=float
-  )
+
+  theo_uses = []
+  for date in dates:
+    for item in projet.alloc_items:
+      if date >= item.start_date.date() and \
+         date <= item.end_date.date():
+        poly_theo  = item.theo_eq
+        break
+    theo_uses.append(100. * poly_theo(dates.index(date)))
+  delay_uses = delay * [0.,] + theo_uses[:-delay]
+  theo_uses = np.array(theo_uses, dtype=float)
+  delay_uses = np.array(delay_uses, dtype=float)
+
 
   run_mean = np.array([item.run_mean for item in selected_items],
@@ -630,38 +614,47 @@
   # ... Plot data ...
   # -----------------
-  plot_data(ax_conso, ax_theo, xcoord, dates,
-            consos, theo_uses, real_uses, theo_equs, theo_delay,
-            run_mean, pen_mean, run_std, pen_std)
+  plot_data(
+    ax_conso, ax_theo, xcoord, dates,
+    consos, real_uses, theo_uses, delay_uses,
+    run_mean, pen_mean, run_std, pen_std
+  )
 
   # ... Tweak figure ...
   # --------------------
-  title = "Consommation {}\n({:%d/%m/%Y} - {:%d/%m/%Y})".format(
+  # title = "Consommation {}\n({:%d/%m/%Y} - {:%d/%m/%Y})".format(
+  #   projet.project.upper(),
+  #   projet.start_date,
+  #   projet.end_date
+  # )
+  title = "Consommation {}\n(le {:%d/%m/%Y})".format(
     projet.project.upper(),
-    projet.start_date,
-    projet.end_date
+    today,
   )
 
   plot_config(
-    fig, ax_conso, ax_theo, xcoord, dates, title,
-    conso_per_day, conso_per_day_2
-  )
+    fig, ax_conso, ax_theo,
+    xcoord, dates, real_uses[dates.index(last_filled_date)],
+    title, projet
+  )
+
+  
 
   # ... Save figure ...
   # -------------------
-  # img_in  = os.path.join(DIR["PLOT"], "{}.pdf".format(img_name))
-  # img_out = os.path.join(DIR["SAVEPLOT"],
-  #                        "{}_{}.pdf".format(img_name, today))
-  img_in  = os.path.join(".", "{}.pdf".format(img_name))
-  img_out = os.path.join(".",
-                         "{}_{}.pdf".format(img_name, today))
-
-  plot_save(img_in, img_out, title)
-
-  # # ... Publish figure on dods ...
-  # # ------------------------------
-  # if args.dods:
-  #   if args.verbose:
-  #     print("Publish figure on dods")
-  #   dods_cp(img_in, DIR)
+  img_out = os.path.join(
+    DIR["PLOT"], args.center, args.project,
+    "{}_{:%Y%m%d}.pdf".format(img_name, today)
+  )
+  if args.verbose:
+    print("Save image as {}".format(img_out))
+
+  plot_save(img_out, title)
+
+  # ... Publish figure on dods ...
+  # ------------------------------
+  if args.dods:
+    if args.verbose:
+      print("Publish figure on dods")
+    dods_cp(img_out, img_name, DODS)
 
   # if args.show:
Index: /TOOLS/ConsoGENCI/trunk/card/config_center_project.ini.init
===================================================================
--- /TOOLS/ConsoGENCI/trunk/card/config_center_project.ini.init	(revision 2775)
+++ /TOOLS/ConsoGENCI/trunk/card/config_center_project.ini.init	(revision 2775)
@@ -0,0 +1,13 @@
+[projet]
+name: project_name
+
+[directories]
+ROOT_DIR: /path/to/ConsoGENCI
+DATA: %(ROOT_DIR)s/data
+PLOT: %(ROOT_DIR)s/plot
+DODS
+
+[dods]
+DIR: /path/to/dods/ConsoGENCI
+USER: user
+SERVER: host
Index: /TOOLS/ConsoGENCI/trunk/misc/idris_scripts/bin/recolte.sh
===================================================================
--- /TOOLS/ConsoGENCI/trunk/misc/idris_scripts/bin/recolte.sh	(revision 2775)
+++ /TOOLS/ConsoGENCI/trunk/misc/idris_scripts/bin/recolte.sh	(revision 2775)
@@ -0,0 +1,77 @@
+#!/bin/ksh
+
+# ==================================================================== #
+# Author: Sonia Labetoulle                                             #
+# Contact: sonia.labetoulle _at_ ipsl.jussieu.fr                       #
+# Created: September 3 2015                                            #
+# History:                                                             #
+# Modification:                                                        #
+# ==================================================================== #
+
+echo "Saving cpt info on $( date )"
+echo "========================================================================"
+
+date_amj=$( \
+  cpt | grep "mise a jour" | \
+  gawk '{ print $6 }' | \
+  gawk -F"/" '{ print $3$2$1 }' \
+)
+echo "date_amj = >${date_amj}<"
+
+date_hm=$( \
+  cpt | grep "mise a jour" | \
+  gawk '{ print $7 }' | \
+  gawk -F":" '{ print $1$2 }' \
+)
+echo "date_hm  = >${date_hm}<"
+
+echo "========================================================================"
+
+local_dir="data"
+# remote_dir="/data/slipsl/ConsoGENCI"
+remote_dir="/home_local/slipsl/ConsoGENCI/data/idris/tmp"
+remote_login="slipsl"
+# remote_host="ciclad.ipsl.jussieu.fr"
+remote_host="pc-236"
+bounce_host="calcul2.ipsl.jussieu.fr"
+bounce_login=${remote_login}
+
+echo "local_dir    = >${local_dir}<"
+echo "remote_dir   = >${remote_dir}<"
+echo "remote_login = >${remote_login}<"
+echo "remote_host  = >${remote_host}<"
+echo "bounce_host  = >${bounce_host}<"
+echo "bounce_login = >${bounce_login}<"
+
+local_fileout="compta_${date_amj}_${date_hm}.dat"
+remote_fileout="cpt_idris_rgzi_${date_amj}_${date_hm}.dat"
+
+echo ""
+echo "local_fileout  = >${local_fileout}<"
+echo "remote_fileout = >${remote_fileout}<"
+
+ssh_options="-T -ax -o ClearAllForwardings=yes -c blowfish"
+
+echo ""
+echo "ssh_options = >${ssh_options}<"
+
+echo "========================================================================"
+
+if [ -f "${local_dir}/${local_fileout}" ] ; then
+  echo "         !!!!!         Local file already exists.         !!!!!         "
+  echo "========================================================================"
+fi
+
+set -vx
+
+cpt > ${local_dir}/${local_fileout}
+
+rsync -va -e "ssh ${ssh_options} ${bounce_login}@${bounce_host} ssh ${ssh_options}" \
+             ${local_dir}/${local_fileout} \
+             ${remote_login}@${remote_host}:${remote_dir}/${remote_fileout}
+
+set +vx
+
+echo "========================================================================"
+echo "Step ended on $( date )"
+
Index: /TOOLS/ConsoGENCI/trunk/misc/idris_scripts/job_conso
===================================================================
--- /TOOLS/ConsoGENCI/trunk/misc/idris_scripts/job_conso	(revision 2775)
+++ /TOOLS/ConsoGENCI/trunk/misc/idris_scripts/job_conso	(revision 2775)
@@ -0,0 +1,81 @@
+#!/bin/ksh
+#=========== Global directives ===========
+# @ job_name = conso
+# @ shell = /bin/ksh
+# @ output = log/$(job_name).$(step_name).$(jobid)
+# @ error = $(output)
+## Date de demarrage calculee
+#STARTDATE 
+## Pour adapp
+# @ requirements = (Feature == "prepost")
+
+#=========== Step 1 directives ===========
+#============== Before execution =================
+# @ step_name = before_execution
+## Pour adapp
+# @ requirements = (Feature == "prepost")
+## Type de travail
+# @ job_type = serial
+## Temp CPU max
+# @ wall_clock_limit = 1:00:00
+# @ queue
+
+#=========== Step 2 directives ===========
+#============= Execution =============
+# @ step_name = execution
+## Dependance
+# @ dependency = (before_execution == 0)
+## Pour adapp
+# @ requirements = (Feature == "prepost")
+## Type de travail
+# @ job_type = serial
+## Temp CPU max
+# @ wall_clock_limit = 1:00:00
+# @ queue
+
+# #=========== Step 3 directives ===========
+# #============== After execution =================
+# # @ step_name = after_execution
+# ## Dependance
+# # @ dependency = (execution == 0)
+# ## Pour adapp
+# # @ requirements = (Feature == "prepost")
+# ## Type de travail
+# # @ job_type = serial
+# ## Temp CPU max
+# # @ wall_clock_limit = 1:00:00
+# # @ queue
+
+case ${LOADL_STEP_NAME} in 
+  #============ Step 1 commands ============ 
+  #======= Sequential preprocessing ========
+  before_execution )
+    set -vx
+    # ${LOADL_STEP_INITDIR} == repertoire ou a ete fait le llsubmit
+    cd ${LOADL_STEP_INITDIR}
+    # Calcul de la date suivante : + 1 jours
+    #demain=$(date "+%m/%d/%Y %H:%M" --date "+1 days")
+    demain=$(date "+%m/%d/%Y 23:00" --date "+1 days")
+    sed s%^#STARTDATE%"# @ startdate = ${demain}"%g job_conso > job_tmp
+    # Soumission de la prochaine recolte
+    llsubmit job_tmp
+    rm job_tmp
+  ;;
+
+  #=========== Step 2 directives ===========
+  #========== Sequential execution =========
+  execution )
+    set -vx
+    ${LOADL_STEP_INITDIR}/bin/recolte.sh
+  ;;
+
+  # #=========== Step 3 directives ===========
+  # #============ After execution ============
+  # after_execution )
+  #   set -vx
+  #   cd ${LOADL_STEP_INITDIR}
+  #   echo "Ok!" > done.txt
+  # ;; 
+
+esac 
+
Index: /TOOLS/ConsoGENCI/trunk/misc/idris_scripts/job_conso_first
===================================================================
--- /TOOLS/ConsoGENCI/trunk/misc/idris_scripts/job_conso_first	(revision 2775)
+++ /TOOLS/ConsoGENCI/trunk/misc/idris_scripts/job_conso_first	(revision 2775)
@@ -0,0 +1,81 @@
+#!/bin/ksh
+#=========== Global directives ===========
+# @ job_name = conso
+# @ shell = /bin/ksh
+# @ output = log/$(job_name).$(step_name).$(jobid)
+# @ error = $(output)
+## Date de demarrage calculee
+# @ startdate = 09/29/2015 23:00
+## Pour adapp
+# @ requirements = (Feature == "prepost")
+
+#=========== Step 1 directives ===========
+#============== Before execution =================
+# @ step_name = before_execution
+## Pour adapp
+# @ requirements = (Feature == "prepost")
+## Type de travail
+# @ job_type = serial
+## Temp CPU max
+# @ wall_clock_limit = 1:00:00
+# @ queue
+
+#=========== Step 2 directives ===========
+#============= Execution =============
+# @ step_name = execution
+## Dependance
+# @ dependency = (before_execution == 0)
+## Pour adapp
+# @ requirements = (Feature == "prepost")
+## Type de travail
+# @ job_type = serial
+## Temp CPU max
+# @ wall_clock_limit = 1:00:00
+# @ queue
+
+# #=========== Step 3 directives ===========
+# #============== After execution =================
+# # @ step_name = after_execution
+# ## Dependance
+# # @ dependency = (execution == 0)
+# ## Pour adapp
+# # @ requirements = (Feature == "prepost")
+# ## Type de travail
+# # @ job_type = serial
+# ## Temp CPU max
+# # @ wall_clock_limit = 1:00:00
+# # @ queue
+
+case ${LOADL_STEP_NAME} in 
+  #============ Step 1 commands ============ 
+  #======= Sequential preprocessing ========
+  before_execution )
+    set -vx
+    # ${LOADL_STEP_INITDIR} == repertoire ou a ete fait le llsubmit
+    cd ${LOADL_STEP_INITDIR}
+    # Calcul de la date suivante : + 1 jours
+    #demain=$(date "+%m/%d/%Y %H:%M" --date "+1 days")
+    demain=$(date "+%m/%d/%Y 23:00" --date "+1 days")
+    sed s%^#STARTDATE%"# @ startdate = ${demain}"%g job_conso > job_tmp
+    # Soumission de la prochaine recolte
+    llsubmit job_tmp
+    rm job_tmp
+  ;;
+
+  #=========== Step 2 directives ===========
+  #========== Sequential execution =========
+  execution )
+    set -vx
+    ${LOADL_STEP_INITDIR}/bin/recolte.sh
+  ;;
+
+  # #=========== Step 3 directives ===========
+  # #============ After execution ============
+  # after_execution )
+  #   set -vx
+  #   cd ${LOADL_STEP_INITDIR}
+  #   echo "Ok!" > done.txt
+  # ;; 
+
+esac 
+
Index: /TOOLS/ConsoGENCI/trunk/misc/local_scripts/cron.txt
===================================================================
--- /TOOLS/ConsoGENCI/trunk/misc/local_scripts/cron.txt	(revision 2775)
+++ /TOOLS/ConsoGENCI/trunk/misc/local_scripts/cron.txt	(revision 2775)
@@ -0,0 +1,5 @@
+# mm hh DD MM w
+   0 */2 *  * * cd /home_local/slipsl/ConsoGENCI ; /opt/epd7/bin/python bin/insert_conso_tbl.py -v   rgzi     idris >& log/insert_conso_tbl_rgzi_`date +\%Y\%m\%d_\%H\%M`.log
+   0 */2 *  * * cd /home_local/slipsl/ConsoGENCI ; /opt/epd7/bin/python bin/insert_conso_tbl.py -v   gencmip6 tgcc  >& log/insert_conso_tbl_gencmip6_`date +\%Y\%m\%d_\%H\%M`.log
+   0 */2 *  * * cd /home_local/slipsl/ConsoGENCI ; /opt/epd7/bin/python bin/plot_bilan.py       -vdf rgzi     idris >& log/bilan_rgzi_`date +\%Y\%m\%d`.log
+   0 */2 *  * * cd /home_local/slipsl/ConsoGENCI ; /opt/epd7/bin/python bin/plot_bilan.py       -vdf gencmip6 tgcc  >& log/bilan_gencmip6_`date +\%Y\%m\%d`.log
Index: /TOOLS/ConsoGENCI/trunk/misc/rename_cpt.py
===================================================================
--- /TOOLS/ConsoGENCI/trunk/misc/rename_cpt.py	(revision 2775)
+++ /TOOLS/ConsoGENCI/trunk/misc/rename_cpt.py	(revision 2775)
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# ==================================================================== #
+# Author: Sonia Labetoulle                                             #
+# Contact: sonia.labetoulle _at_ ipsl.jussieu.fr                       #
+# Created: 2016                                                        #
+# History:                                                             #
+# Modification:                                                        #
+# ==================================================================== #
+
+"""
+  Rename files from :
+    - TGCC "ccc_myproject" (ccc_myproject.dat_20150602)
+    - IDRIS "cpt" (compta_20151206_0643.dat)
+  to a common nomenclature:
+    => cpt_[center]_[project]_[ssaammjj]_[hhmm].dat
+"""
+
+# this must come first
+from __future__ import print_function, unicode_literals, division
+
+# standard library imports
+import os
+import glob
+import shutil
+
+
+#######################################################################
+if __name__ == '__main__':
+
+  dirin = "/home_local/slipsl/ConsoGENCMIP6/init_db/data"
+  dirout = "/home_local/slipsl/ConsoGENCI/data"
+  file_list = glob.glob(os.path.join(dirin, "*.dat*"))
+
+  for src in file_list:
+    filein = os.path.basename(src)
+
+    if "ccc_myproject" in filein:
+      centre = "tgcc"
+      projet = "gencmip6"
+      _, _, date = filein.split("_")
+      heure  = "2359"
+    elif "compta" in filein:
+      centre = "idris"
+      projet = "rgzi"
+      _, date, heure = filein.split("_")
+      heure, _ = heure.split(".")
+
+    fileout = "cpt_{}_{}_{}_{}.dat".format(centre, projet, date, heure)
+    dst = os.path.join(dirout, centre, projet, fileout)
+
+    if not os.path.isfile(dst):
+      print("copy {} to\n     {}".format(src, dst))
+      shutil.copy(src, dst)
Index: /TOOLS/ConsoGENCI/trunk/misc/tgcc_scripts/cron.txt
===================================================================
--- /TOOLS/ConsoGENCI/trunk/misc/tgcc_scripts/cron.txt	(revision 2775)
+++ /TOOLS/ConsoGENCI/trunk/misc/tgcc_scripts/cron.txt	(revision 2775)
@@ -0,0 +1,4 @@
+ 0  6 *   * * cd /ccc/cont003/home/dsm/p86ipsl/CCC_MYPROJECT ; ./bin/conso_gencmip6_v4 > log/conso_gencmip6_v4.log 2>&1
+ 0  6 *   * * cd /ccc/cont003/home/dsm/p86ipsl/ConsoGENCMIP6 ; ./launch_conso.sh > log/conso_gencmip6_py.log 2>&1
+ 0  * *   * * cd /ccc/cont003/home/dsm/p86ipsl/ConsoGENCMIP6 ; ./launch_jobs.sh > log/jobs_gencmip6_py.log 2>&1
+
