1 module dsurf.io.iraploader;
2 
3 import std.conv;
4 import std.stdio; 
5 import std.file;
6 import std..string;
7 import std.conv;
8 import std.math;
9 
10 import dsurf.cartesian;
11 import dsurf.io.loader;
12 
13 /**
14 Class that provides loading of IRAP Classic ASCII (aka ROXAR text) files
15 */
16 class IrapLoader : CartesianSurfaceLoader 
17 {
18     /// Loads an IRAP Classic ASCII (aka ROXAR text) surface from a file in a given path
19     override CartesianSurface load(string fileName) {
20         if (!exists(fileName))
21             throw new Exception("File " ~ fileName ~ " doesn't exist");
22         File file = File(fileName, "r");
23         auto surface = new CartesianSurface;
24         bool readingHeader = true;
25         int i = -1;
26         int j = -1;
27         double xOrigin = double.nan, yOrigin = double.nan;
28         double xMax = double.nan, yMax = double.nan;
29         double dx = double.nan, dy = double.nan;
30         int nx = -1, ny = -1;
31         immutable double blank = 9_999_900;
32         while(!file.eof()) {
33             string line = file.readln().chomp().replace("\"", "");
34             auto words = line.split();
35             if (readingHeader) {
36                 if (isNaN(dx)) {
37                     if (words.length < 4)
38                         throw new Exception("Invalid header, line 1: " ~ line);
39                     ny = words[1].to!int;
40                     dx = words[2].to!double;
41                     dy = words[3].to!double;
42                 }
43                 else if (isNaN(xOrigin)) {
44                     if (words.length < 4)
45                         throw new Exception("Invalid header, line 2: " ~ line);
46                     xOrigin = words[0].to!double;
47                     xMax = words[1].to!double;
48                     yOrigin = words[2].to!double;
49                     yMax = words[3].to!double;
50                 }
51                 else if (nx < 0) {
52                     nx = words[0].to!int;
53                 }
54                 else {
55                     surface.setHeader(nx, ny, xOrigin, yOrigin, dx, dy);
56                     readingHeader = false;
57                     i = 0;
58                     j = 0;
59                 }
60             }
61             else {
62                 if (i < 0 || j < 0)
63                     throw new Exception("Invalid index");  //TODO add some information
64                 if (words.empty)
65                     continue;
66                 if (words[0].startsWith("+"))  //RMS specific
67                     continue;
68                 foreach (word; words) {
69                     double value = 0;
70                     try
71                         value = to!double(word);
72                     catch (ConvException e)
73                         value = double.nan;
74                     if (value == blank)
75                         surface.z[i][j] = double.nan;
76                     else
77                         surface.z[i][j] = value;
78                     
79                     i++;
80                     if (i >= surface.nx) {
81                         j++;
82                         i = 0;
83                     }
84                 }
85             }
86         }
87         if (surface.nx == 0 || 
88             surface.ny == 0 || 
89             surface.dx == 0 || 
90             surface.dy == 0)
91             throw new Exception("Invalid header");
92         return surface;
93     }
94 }