difffloat.py 4.26 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
###############################################################################
 # This file is part of SWIFT.
 # Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
 # 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Lesser General Public License as published
 # by the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # 
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # 
 # You should have received a copy of the GNU Lesser General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # 
 ##############################################################################

from numpy import *
import sys

abs_tol = 1e-7
rel_tol = 1e-7

# Compares the content of two ASCII tables of floats line by line and
# reports all differences beyond the given tolerances
28
29
30
# Comparisons are done both in absolute and relative terms

# Individual tolerances for each column can be provided in a file
31
32
# The (cube root of) the number of lines to check is provided as
# an optional 4th argument
33
34
35

file1 = sys.argv[1]
file2 = sys.argv[2]
36
37
38
39
number_to_check = -1

fileTol = ""
if len(sys.argv) >= 4:
40
    fileTol = sys.argv[3]
41

42
43
44
45
46
47
48
if len(sys.argv) >= 5:
    number_to_check = int(sys.argv[4])

if len(sys.argv) == 6:
    ignoreSmallRhoDh = int(sys.argv[5])
else:
    ignoreSmallRhoDh = 0
49
50
51
52
53
54
55

# Get the particle properties being compared from the header.
with open(file1, 'r') as f:
  line = f.readline()
  if 'ID' in line:
    part_props = line.split()[1:]

56
57
data1 = loadtxt(file1)
data2 = loadtxt(file2)
58
59
60
61
62
if fileTol != "":
    dataTol = loadtxt(fileTol)
    n_linesTol = shape(dataTol)[0]
    n_columnsTol = shape(dataTol)[1]

63
64
65
66
67
68
69
70

if shape(data1) != shape(data2):
    print "Non-matching array sizes in the files", file1, "and", file2, "."
    sys.exit(1)

n_lines = shape(data1)[0]
n_columns = shape(data1)[1]

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
if fileTol != "":
    if n_linesTol != 2:
        print "Incorrect number of lines in tolerance file '%s'."%fileTol
    if n_columnsTol != n_columns:
        print "Incorrect number of columns in tolerance file '%s'."%fileTol

if fileTol == "":
    print "Absolute difference tolerance:", abs_tol
    print "Relative difference tolerance:", rel_tol
    absTol = ones(n_columns) * abs_tol
    relTol = ones(n_columns) * rel_tol
else:
    print "Tolerances read from file"
    absTol = dataTol[0,:]
    relTol = dataTol[1,:]

87
88
89
90
91
92
93
94
95
n_lines_to_check = 0
if number_to_check > 0:
    n_lines_to_check = number_to_check**3
    n_lines_to_check = min(n_lines_to_check, n_lines)
    print "Checking the first %d particles."%n_lines_to_check
else:
    n_lines_to_check = n_lines
    print "Checking all particles in the file."

96
error = False
97
for i in range(n_lines_to_check):
98
99
100
101
102
103
104
105
    for j in range(n_columns):

        abs_diff = abs(data1[i,j] - data2[i,j])

        sum = abs(data1[i,j] + data2[i,j])
        if sum > 0:
            rel_diff = abs(data1[i,j] - data2[i,j]) / sum
        else:
106
            rel_diff = 0.
107

108
        if( abs_diff > 1.1*absTol[j]):
109
            print "Absolute difference larger than tolerance (%e) for particle %d, column %s:"%(absTol[j], data1[i,0], part_props[j])
110
111
112
            print "%10s:           a = %e"%("File 1", data1[i,j])
            print "%10s:           b = %e"%("File 2", data2[i,j])
            print "%10s:       |a-b| = %e"%("Difference", abs_diff)
113
114
115
            print ""
            error = True

116
        if abs(data1[i,j]) < 4e-6 and abs(data2[i,j]) < 4e-6 : continue
117
118
119
120

        # Ignore pathological cases with rho_dh
        if ignoreSmallRhoDh and j == 8 and abs(data1[i,j]) < 2e-4: continue
        
121
        if( rel_diff > 1.1*relTol[j]):
122
            print "Relative difference larger than tolerance (%e) for particle %d, column %s:"%(relTol[j], data1[i,0], part_props[j])
123
124
125
            print "%10s:           a = %e"%("File 1", data1[i,j])
            print "%10s:           b = %e"%("File 2", data2[i,j])
            print "%10s: |a-b|/|a+b| = %e"%("Difference", rel_diff)
126
127
128
129
130
            print ""
            error = True


if error:
131
    exit(1)
132
133
else:
    print "No differences found"
134
    exit(0)