# GP_DATAFILE.PY
# Dominic Ford
# 12/04/2006

import gp_eval
import gp_settings

import os
import re

# GP_DATAREAD(): Read a data file, selecting only every nth item from index m, using ....

def gp_dataread(datafile, index, using, every, vars, funcs):
  rows       = 0
  using_list = gp_eval.gp_split(using, ":")
  columns    = len(using_list)
  data_used  = {}
  datagrid   =  []
  totalgrid  = [[]] # List of [rows, columns, datagrid]s
  allgrid    =  []

  # Parse using list
  for i in range(len(using_list)):
    test = re.match(r"""^[0-9]*$""",using_list[i])
    if (test != None):
      data_used[int(test.group(0))]='used'
      using_list[i] = "_gp_param"+using_list[i]
    else:
      while 1:
        test = re.search(r"\$([0-9]*)",using_list[i])
        if (test != None):
          using_list[i] = using_list[i][:test.start()] + "_gp_param" + test.group(1) + using_list[i][test.end():]
          data_used[int(test.group(1))]='used'
        else:
          break

  # Open input datafile
  f          = open(os.path.join(gp_settings.cwd, datafile),"r")
  index_no   = 0
  every_count= 0
  prev_blank = 10 # Skip opening blank lines
  vars_local = vars.copy()

  for line in f.readlines():
    line_clean = line.strip()
    if (len(line_clean) == 0): # Ignore blank lines
      prev_blank = prev_blank + 1
      if (rows > 0):           # Make a new discontinuous line
       totalgrid.append([rows,columns,datagrid])
       rows = 0
       datagrid = []
      if (prev_blank == 2): # Two blank lines means a new index
       index_no = index_no + 1
       if ((index >= 0) and (index_no > index)): break # No more data
      continue
    if (line_clean[0] == '#'): continue # Ignore comment lines, too
    prev_blank = 0 # Reset blank lines counter

    if ((index >= 0) and (index_no != index)): continue # Still waiting for our index

    if (every_count < 1): # Use only every nth datapoint
      data_item = []
      data_list = line_clean.split()
      for varnum,dummy in data_used.iteritems():
        if (varnum <= len(data_list)):
          vars_local['_gp_param'+str(varnum)] = float(data_list[varnum-1])
        else:
          vars_local['_gp_param'+str(varnum)] = 0.0
      for i in range(len(using_list)):
        data_item.append(gp_eval.gp_eval(using_list[i], vars_local, funcs))
      datagrid.append(data_item)
      allgrid.append(data_item)
      rows = rows + 1
      every_count = every - 1
    else:
      every_count = every_count - 1 # Count down counter until we take next point

  f.close()
  if (rows > 0): totalgrid.append([rows,columns,datagrid])
  totalgrid[0] = [rows, columns, allgrid]
  return totalgrid
