1 module dsurf.io.cpsloader;
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 CPS3 ASCII files
15 */
16 class Cps3Loader : CartesianSurfaceLoader 
17 {
18     /// Loads a CPS3 ASCII 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 = -1, yOrigin = -1;
28         double dx = -1, dy = -1;
29         int nx = -1, ny = -1;
30         double blank = 1e31;
31         while(!file.eof()) {
32             string line = file.readln().chomp().replace("\"", "");
33             if (!line)
34                 continue;
35             if (readingHeader) {
36                 auto words = line.split();
37                 if (words[0] == "FSASCI") {
38                     blank = words[$ - 1].to!double;
39                 }
40                 if (words[0] == "FSLIMI") {
41                     xOrigin = words[1].to!double;
42                     yOrigin = words[3].to!double;
43                 }
44                 else if (words[0] == "FSNROW") {
45                     nx = words[2].to!int;
46                     ny = words[1].to!int;
47                 }
48                 else if (words[0] == "FSXINC") {
49                     dx = words[1].to!double;
50                     dy = words[2].to!double;
51                     readingHeader = false;
52                     surface.setHeader(nx, ny, xOrigin, yOrigin, dx, dy);
53                     i = 0;
54                     j = ny - 1;
55                 }
56             }
57             else {
58                 if (surface.nx == 0 || 
59                     surface.ny == 0 || 
60                     surface.dx == 0 || 
61                     surface.dy == 0)
62                     throw new Exception("Invalid header");
63                 if (i < 0 || j < 0)
64                     throw new Exception("Invalid index");  //TODO add some information
65                 auto words = line.split();
66                 if (words[0].startsWith("->"))  //petrel 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                     j--;
80                     if (j < 0) {
81                         i++;
82                         j = surface.ny() - 1;
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 }