#### Script to check the output of algorithms:
### Author: <NAME> (<EMAIL>)
### Modified to calculate error + take tolerance as an error by Loc Hoang 

### python script.py masterFile allfile* [-t, -tolerance]=<tolerance>

### expects files in the follwing format:
###### nodeID nodeFieldVal
######## These are generated by galois::runtime::printOutput function.
### Requires python version > 2.7
# Can also take 2 field files TODO make more general

import sys
import argparse

def check_results(masterFile, otherFiles, offset, errors, mrows, tolerance):
  global_error = 0
  global_error_squared = 0
  num_nodes = 0

  with open(masterFile) as mfile, open(otherFiles) as ofile:
    mfile.seek(offset)

    for line2 in ofile:
      line1 = mfile.readline()
      offset = offset + len(line1)

      split_line1 = line1.split(' ')
      split_line2 = line2.split(' ')

      if (split_line1[0] == ''):
        print("ERROR: output longer than input")
        return (0, errors, mrows)

      while (long(split_line1[0]) < long(split_line2[0])):
        print "MISSING ROW: ", split_line1[0]
        mrows = mrows + 1
        line1 = mfile.readline()
        offset = offset + len(line1)
        split_line1 = line1.split(' ')


      # forces failure if missings rows exist
      #if mrows > 0:
      #  return (-1, errors, mrows)

      if (long(split_line1[0]) == long(split_line2[0])):
        # absolute value of difference in fields
        field_difference = abs(float(split_line1[1]) - float(split_line2[1]))

        global_error_squared += (field_difference * field_difference)
        num_nodes += 1

        if (field_difference > tolerance):
          print "NOT MATCHED \n";
          print line1;
          print line2;
          errors = errors + 1;
        # TODO (Loc) make more general: deals with 2 fields in output (should
        # optimally deal with arbitrary # of fields
        elif (len(split_line1) == 3):
          field_difference2 = abs(float(split_line1[2]) - float(split_line2[2]))
          if (field_difference2 > tolerance):
            print "NOT MATCHED \n";
            print line1;
            print line2;
            errors = errors + 1;
      else:
        print "OFFSET MISMATCH: ", split_line1[0], split_line2[0]
        return (-1, errors, mrows);

  print("Mean error squared (for first field) is %f\n" % (global_error_squared / num_nodes))
  return (offset, errors, mrows);

def main(masterFile, allFiles_arr, tolerance):
  offset = 0;
  errors = 0;
  mrows = 0;

  for i in range(0 , len(allFiles_arr)):
    print allFiles_arr[i]
    print offset
    offset, errors, mrows = check_results(masterFile, allFiles_arr[i], offset, 
                                          errors, mrows, tolerance)
    if (offset == -1):
      break;

  if (offset != -1):
    mfile = open(masterFile)
    mfile.seek(offset)
    old_mrows=mrows
    for line in mfile:
      mrows = mrows + 1
    if mrows > old_mrows:
      print "INCOMPLETE OUTPUT FILE"
  print "No of offsets/rows missing", mrows;

  if (errors > 0):
    print "No of mismatches", errors;
    print "\nFAILED\n";

  if (offset == -1):
    print "\nOFFSET NOT CORRECT\n";

  if (errors > 0) or (offset == -1):
    print allFiles_arr[i];
    return -1;

  return 0;

if __name__ == "__main__":
  parser = argparse.ArgumentParser(description="Check graph output results")

  # parse files and an optional tolerance
  parser.add_argument('files', type=str, nargs='+', help='input + output files')
  parser.add_argument('-tolerance', '-t', type=float, nargs=1, default=0.0001,
                      help='tolerance for difference in fields')

  arg = sys.argv
  parsed_arguments = parser.parse_args()

  masterFile = parsed_arguments.files[0]
  allFiles_arr = parsed_arguments.files[1:]

  print masterFile  
  print allFiles_arr  

  tolerance = parsed_arguments.tolerance

  print("Starting comparison...")

  # apparently if you pass in a tolerance argument it returns it as a list...
  # the default is just a float
  if isinstance(tolerance, list):
    ret = main(masterFile, allFiles_arr, tolerance[0])
  else:
    ret = main(masterFile, allFiles_arr, tolerance)

  if(ret == 0):
    print "\nSUCCESS\n";

#### Script to check the output of algorithms:
### Author: <NAME> (<EMAIL>)
### Modified to calculate error + take tolerance as an error by Loc Hoang 

### python script.py masterFile allfile* [-t, -tolerance]=<tolerance>

### expects files in the follwing format:
###### nodeID nodeFieldVal
######## These are generated by galois::runtime::printOutput function.
### Requires python version > 2.7
# Can also take 2 field files TODO make more general

import sys
import argparse

def check_results(masterFile, otherFiles, offset, errors, mrows, tolerance):
  global_error = 0
  global_error_squared = 0
  num_nodes = 0

  with open(masterFile) as mfile, open(otherFiles) as ofile:
    mfile.seek(offset)

    for line2 in ofile:
      line1 = mfile.readline()
      offset = offset + len(line1)

      split_line1 = line1.split(' ')
      split_line2 = line2.split(' ')

      if (split_line1[0] == ''):
        print("ERROR: output longer than input")
        return (0, errors, mrows)

      while (long(split_line1[0]) < long(split_line2[0])):
        print "MISSING ROW: ", split_line1[0]
        mrows = mrows + 1
        line1 = mfile.readline()
        offset = offset + len(line1)
        split_line1 = line1.split(' ')


      # forces failure if missings rows exist
      #if mrows > 0:
      #  return (-1, errors, mrows)

      if (long(split_line1[0]) == long(split_line2[0])):
        # absolute value of difference in fields
        field_difference = abs(float(split_line1[1]) - float(split_line2[1]))

        global_error_squared += (field_difference * field_difference)
        num_nodes += 1

        if (field_difference > tolerance):
          print "NOT MATCHED \n";
          print line1;
          print line2;
          errors = errors + 1;
        # TODO (Loc) make more general: deals with 2 fields in output (should
        # optimally deal with arbitrary # of fields
        elif (len(split_line1) == 3):
          field_difference2 = abs(float(split_line1[2]) - float(split_line2[2]))
          if (field_difference2 > tolerance):
            print "NOT MATCHED \n";
            print line1;
            print line2;
            errors = errors + 1;
      else:
        print "OFFSET MISMATCH: ", split_line1[0], split_line2[0]
        return (-1, errors, mrows);

  print("Mean error squared (for first field) is %f\n" % (global_error_squared / num_nodes))
  return (offset, errors, mrows);

def main(masterFile, allFiles_arr, tolerance):
  offset = 0;
  errors = 0;
  mrows = 0;

  for i in range(0 , len(allFiles_arr)):
    print allFiles_arr[i]
    print offset
    offset, errors, mrows = check_results(masterFile, allFiles_arr[i], offset, 
                                          errors, mrows, tolerance)
    if (offset == -1):
      break;

  if (offset != -1):
    mfile = open(masterFile)
    mfile.seek(offset)
    old_mrows=mrows
    for line in mfile:
      mrows = mrows + 1
    if mrows > old_mrows:
      print "INCOMPLETE OUTPUT FILE"
  print "No of offsets/rows missing", mrows;

  if (errors > 0):
    print "No of mismatches", errors;
    print "\nFAILED\n";

  if (offset == -1):
    print "\nOFFSET NOT CORRECT\n";

  if (errors > 0) or (offset == -1):
    print allFiles_arr[i];
    return -1;

  return 0;

if __name__ == "__main__":
  parser = argparse.ArgumentParser(description="Check graph output results")

  # parse files and an optional tolerance
  parser.add_argument('files', type=str, nargs='+', help='input + output files')
  parser.add_argument('-tolerance', '-t', type=float, nargs=1, default=0.0001,
                      help='tolerance for difference in fields')

  arg = sys.argv
  parsed_arguments = parser.parse_args()

  masterFile = parsed_arguments.files[0]
  allFiles_arr = parsed_arguments.files[1:]

  print masterFile  
  print allFiles_arr  

  tolerance = parsed_arguments.tolerance

  print("Starting comparison...")

  # apparently if you pass in a tolerance argument it returns it as a list...
  # the default is just a float
  if isinstance(tolerance, list):
    ret = main(masterFile, allFiles_arr, tolerance[0])
  else:
    ret = main(masterFile, allFiles_arr, tolerance)

  if(ret == 0):
    print "\nSUCCESS\n";

#### Script to check the output of algorithms: ### Author: <NAME> (<EMAIL>) ### Modified to calculate error + take tolerance as an error by Loc Hoang ### python script.py masterFile allfile* [-t, -tolerance]=<tolerance> ### expects files in the follwing format: ###### nodeID nodeFieldVal ######## These are generated by galois::runtime::printOutput function. ### Requires python version > 2.7 # Can also take 2 field files TODO make more general # forces failure if missings rows exist #if mrows > 0: #  return (-1, errors, mrows) # absolute value of difference in fields # TODO (Loc) make more general: deals with 2 fields in output (should # optimally deal with arbitrary # of fields # parse files and an optional tolerance # apparently if you pass in a tolerance argument it returns it as a list... # the default is just a float