Task 275: .GW File Format
Task 275: .GW File Format
1. List of all the properties of this file format intrinsic to its file system
The .GW file format is the Groundwater Input Data file used by the Soil & Water Assessment Tool (SWAT), a hydrological model developed by the USDA Agricultural Research Service. It is a plain text file that initializes properties for shallow and deep aquifer systems. The file uses a free-format structure, where each line corresponds to a specific property (variable), with values separated by spaces (blank spaces denote the end of one value and the beginning of the next). Integer variables do not include decimals, while real variables must. The file typically has 17 lines (1 for title, 16 for variables), but optional variables can be omitted (defaults are used). The properties are line-positioned and include initial depths, delay times, thresholds, coefficients, and concentrations for groundwater modeling.
Here is the complete list of properties:
- TITLE (Line 1, character, free format): User comment line (up to 80 characters). Optional; not processed by the model. May be left blank.
- SHALLST (Line 2, real, free format): Initial depth of water in the shallow aquifer (mm H2O). Required for equilibration runs.
- DEEPST (Line 3, real, free format): Initial depth of water in the deep aquifer (mm H2O). Optional; defaults to 1000.0 mm if omitted. No impact if no deep aquifer irrigation.
- GW_DELAY (Line 4, real, free format): Groundwater delay time (days). Required; lag time for water to reach shallow aquifer from soil profile.
- ALPHA_BF (Line 5, real, free format): Baseflow alpha factor (1/days). Required; groundwater flow response index (0.1-1.0).
- GWQMN (Line 6, real, free format): Threshold depth of water in shallow aquifer for return flow (mm H2O). Required.
- GW_REVAP (Line 7, real, free format): Groundwater revap coefficient. Required; controls revap from shallow to unsaturated zone (0.02-0.20).
- REVAPMN (Line 8, real, free format): Threshold depth for revap or percolation to deep aquifer (mm H2O). Required.
- RCHRG_DP (Line 9, real, free format): Deep aquifer percolation fraction. Required; fraction of percolation recharging deep aquifer (0.0-1.0).
- GWHT (Line 10, real, free format): Initial groundwater height (m). Inactive in current versions.
- GW_SPYLD (Line 11, real, free format): Specific yield of the shallow aquifer (m3/m3). Inactive in current versions.
- SHALLST_N (Line 12, real, free format): Initial nitrate concentration in shallow aquifer (mg N/L). Optional.
- GWSOLP (Line 13, real, free format): Soluble phosphorus concentration in groundwater (mg P/L). Optional; fixed for simulation.
- HLIFE_NGW (Line 14, real, free format): Half-life of nitrate in shallow aquifer (days). Optional.
- LAT_ORGN (Line 15, real, free format): Organic N in baseflow (mg/L). Optional; default 0.0.
- LAT_ORGP (Line 16, real, free format): Organic P in baseflow (mg/L). Optional; default 0.0.
- ALPHA_BF_D (Line 17, real, free format): Alpha factor for deep aquifer recession curve (1/days). Optional.
These properties are intrinsic to the file's structure as they define the aquifer initialization and flow parameters in SWAT's groundwater subsystem.
2. Two direct download links for files of format .GW
- https://drive.google.com/uc?export=download&id=18fO-DJxojCMVKaMWjoqrQIluUVsYbIU0 (SWAT+ gwflow tutorial zip containing multiple example .gw files from the 2023 tutorial dataset)
- https://github.com/swat-model/swatplus-editor/releases/download/v3.0.0/SwatPlusEditor_3.0.0.zip (SWAT+ Editor release zip containing sample SWAT+ models with .gw files for groundwater flow testing)
3. Ghost blog embedded html javascript
4. Python class
import os
class GWFile:
def __init__(self, filename):
self.filename = filename
self.properties = {}
self._read()
def _read(self):
if not os.path.exists(self.filename):
raise FileNotFoundError(f"{self.filename} not found")
with open(self.filename, 'r') as f:
lines = [line.strip() for line in f.readlines() if line.strip()]
if lines:
self.properties['title'] = lines[0]
if len(lines) > 1:
self.properties['shallst'] = float(lines[1]) if lines[1] else 0.0
if len(lines) > 2:
self.properties['deepst'] = float(lines[2]) if lines[2] else 1000.0
if len(lines) > 3:
self.properties['gw_delay'] = float(lines[3]) if lines[3] else 0.0
if len(lines) > 4:
self.properties['alpha_bf'] = float(lines[4]) if lines[4] else 0.0
if len(lines) > 5:
self.properties['gwqmn'] = float(lines[5]) if lines[5] else 0.0
if len(lines) > 6:
self.properties['gw_revap'] = float(lines[6]) if lines[6] else 0.0
if len(lines) > 7:
self.properties['revapmn'] = float(lines[7]) if lines[7] else 0.0
if len(lines) > 8:
self.properties['rchrg_dp'] = float(lines[8]) if lines[8] else 0.0
if len(lines) > 9:
self.properties['gwht'] = float(lines[9]) if lines[9] else 0.0
if len(lines) > 10:
self.properties['gw_spyld'] = float(lines[10]) if lines[10] else 0.0
if len(lines) > 11:
self.properties['shallst_n'] = float(lines[11]) if lines[11] else 0.0
if len(lines) > 12:
self.properties['gwsolp'] = float(lines[12]) if lines[12] else 0.0
if len(lines) > 13:
self.properties['hlife_ngw'] = float(lines[13]) if lines[13] else 0.0
if len(lines) > 14:
self.properties['lat_orgn'] = float(lines[14]) if lines[14] else 0.0
if len(lines) > 15:
self.properties['lat_orgp'] = float(lines[15]) if lines[15] else 0.0
if len(lines) > 16:
self.properties['alpha_bf_d'] = float(lines[16]) if lines[16] else 0.0
def write(self, output_filename):
with open(output_filename, 'w') as f:
f.write(f"{self.properties.get('title', '')}\n")
f.write(f"{self.properties.get('shallst', 0.0)}\n")
f.write(f"{self.properties.get('deepst', 1000.0)}\n")
f.write(f"{self.properties.get('gw_delay', 0.0)}\n")
f.write(f"{self.properties.get('alpha_bf', 0.0)}\n")
f.write(f"{self.properties.get('gwqmn', 0.0)}\n")
f.write(f"{self.properties.get('gw_revap', 0.0)}\n")
f.write(f"{self.properties.get('revapmn', 0.0)}\n")
f.write(f"{self.properties.get('rchrg_dp', 0.0)}\n")
f.write(f"{self.properties.get('gwht', 0.0)}\n")
f.write(f"{self.properties.get('gw_spyld', 0.0)}\n")
f.write(f"{self.properties.get('shallst_n', 0.0)}\n")
f.write(f"{self.properties.get('gwsolp', 0.0)}\n")
f.write(f"{self.properties.get('hlife_ngw', 0.0)}\n")
f.write(f"{self.properties.get('lat_orgn', 0.0)}\n")
f.write(f"{self.properties.get('lat_orgp', 0.0)}\n")
f.write(f"{self.properties.get('alpha_bf_d', 0.0)}\n")
def print_properties(self):
for key, value in self.properties.items():
print(f"{key.upper()}: {value}")
# Example usage:
# gw = GWFile('example.gw')
# gw.print_properties()
# gw.write('output.gw')
5. Java class
import java.io.*;
import java.util.HashMap;
import java.util.Map;
public class GWFile {
private String filename;
private Map<String, Object> properties = new HashMap<>();
public GWFile(String filename) {
this.filename = filename;
read();
}
private void read() {
try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
String line;
int lineNum = 0;
while ((line = br.readLine()) != null) {
line = line.trim();
if (line.isEmpty()) continue;
lineNum++;
switch (lineNum) {
case 1 -> properties.put("title", line);
case 2 -> properties.put("shallst", Double.parseDouble(line));
case 3 -> properties.put("deepst", Double.parseDouble(line));
case 4 -> properties.put("gw_delay", Double.parseDouble(line));
case 5 -> properties.put("alpha_bf", Double.parseDouble(line));
case 6 -> properties.put("gwqmn", Double.parseDouble(line));
case 7 -> properties.put("gw_revap", Double.parseDouble(line));
case 8 -> properties.put("revapmn", Double.parseDouble(line));
case 9 -> properties.put("rchrg_dp", Double.parseDouble(line));
case 10 -> properties.put("gwht", Double.parseDouble(line));
case 11 -> properties.put("gw_spyld", Double.parseDouble(line));
case 12 -> properties.put("shallst_n", Double.parseDouble(line));
case 13 -> properties.put("gwsolp", Double.parseDouble(line));
case 14 -> properties.put("hlife_ngw", Double.parseDouble(line));
case 15 -> properties.put("lat_orgn", Double.parseDouble(line));
case 16 -> properties.put("lat_orgp", Double.parseDouble(line));
case 17 -> properties.put("alpha_bf_d", Double.parseDouble(line));
}
}
// Set defaults for missing
properties.putIfAbsent("deepst", 1000.0);
} catch (IOException | NumberFormatException e) {
System.err.println("Error reading file: " + e.getMessage());
}
}
public void write(String outputFilename) {
try (PrintWriter pw = new PrintWriter(new FileWriter(outputFilename))) {
pw.println(properties.getOrDefault("title", ""));
pw.println(properties.getOrDefault("shallst", 0.0));
pw.println(properties.getOrDefault("deepst", 1000.0));
pw.println(properties.getOrDefault("gw_delay", 0.0));
pw.println(properties.getOrDefault("alpha_bf", 0.0));
pw.println(properties.getOrDefault("gwqmn", 0.0));
pw.println(properties.getOrDefault("gw_revap", 0.0));
pw.println(properties.getOrDefault("revapmn", 0.0));
pw.println(properties.getOrDefault("rchrg_dp", 0.0));
pw.println(properties.getOrDefault("gwht", 0.0));
pw.println(properties.getOrDefault("gw_spyld", 0.0));
pw.println(properties.getOrDefault("shallst_n", 0.0));
pw.println(properties.getOrDefault("gwsolp", 0.0));
pw.println(properties.getOrDefault("hlife_ngw", 0.0));
pw.println(properties.getOrDefault("lat_orgn", 0.0));
pw.println(properties.getOrDefault("lat_orgp", 0.0));
pw.println(properties.getOrDefault("alpha_bf_d", 0.0));
} catch (IOException e) {
System.err.println("Error writing file: " + e.getMessage());
}
}
public void printProperties() {
for (Map.Entry<String, Object> entry : properties.entrySet()) {
System.out.println(entry.getKey().toUpperCase() + ": " + entry.getValue());
}
}
// Example usage:
// public static void main(String[] args) { GWFile gw = new GWFile("example.gw"); gw.printProperties(); gw.write("output.gw"); }
}
6. Javascript class
const fs = require('fs');
class GWFile {
constructor(filename) {
this.filename = filename;
this.properties = {};
this.read();
}
read() {
try {
const text = fs.readFileSync(this.filename, 'utf8');
const lines = text.split('\n').map(l => l.trim()).filter(l => l);
if (lines[0]) this.properties.title = lines[0];
if (lines[1]) this.properties.shallst = parseFloat(lines[1]) || 0.0;
if (lines[2]) this.properties.deepst = parseFloat(lines[2]) || 1000.0;
if (lines[3]) this.properties.gw_delay = parseFloat(lines[3]) || 0.0;
if (lines[4]) this.properties.alpha_bf = parseFloat(lines[4]) || 0.0;
if (lines[5]) this.properties.gwqmn = parseFloat(lines[5]) || 0.0;
if (lines[6]) this.properties.gw_revap = parseFloat(lines[6]) || 0.0;
if (lines[7]) this.properties.revapmn = parseFloat(lines[7]) || 0.0;
if (lines[8]) this.properties.rchrg_dp = parseFloat(lines[8]) || 0.0;
if (lines[9]) this.properties.gwht = parseFloat(lines[9]) || 0.0;
if (lines[10]) this.properties.gw_spyld = parseFloat(lines[10]) || 0.0;
if (lines[11]) this.properties.shallst_n = parseFloat(lines[11]) || 0.0;
if (lines[12]) this.properties.gwsolp = parseFloat(lines[12]) || 0.0;
if (lines[13]) this.properties.hlife_ngw = parseFloat(lines[13]) || 0.0;
if (lines[14]) this.properties.lat_orgn = parseFloat(lines[14]) || 0.0;
if (lines[15]) this.properties.lat_orgp = parseFloat(lines[15]) || 0.0;
if (lines[16]) this.properties.alpha_bf_d = parseFloat(lines[16]) || 0.0;
} catch (err) {
console.error('Error reading file:', err.message);
}
}
write(outputFilename) {
const content = [
this.properties.title || '',
this.properties.shallst || 0.0,
this.properties.deepst || 1000.0,
this.properties.gw_delay || 0.0,
this.properties.alpha_bf || 0.0,
this.properties.gwqmn || 0.0,
this.properties.gw_revap || 0.0,
this.properties.revapmn || 0.0,
this.properties.rchrg_dp || 0.0,
this.properties.gwht || 0.0,
this.properties.gw_spyld || 0.0,
this.properties.shallst_n || 0.0,
this.properties.gwsolp || 0.0,
this.properties.hlife_ngw || 0.0,
this.properties.lat_orgn || 0.0,
this.properties.lat_orgp || 0.0,
this.properties.alpha_bf_d || 0.0
].join('\n') + '\n';
fs.writeFileSync(outputFilename, content);
}
printProperties() {
for (const [key, value] of Object.entries(this.properties)) {
console.log(`${key.toUpperCase()}: ${value}`);
}
}
}
// Example usage:
// const gw = new GWFile('example.gw');
// gw.printProperties();
// gw.write('output.gw');
7. C class
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char title[256];
double shallst;
double deepst;
double gw_delay;
double alpha_bf;
double gwqmn;
double gw_revap;
double revapmn;
double rchrg_dp;
double gwht;
double gw_spyld;
double shallst_n;
double gwsolp;
double hlife_ngw;
double lat_orgn;
double lat_orgp;
double alpha_bf_d;
} GWProperties;
typedef struct {
char filename[256];
GWProperties props;
} GWFile;
void read_gw(GWFile *gw) {
FILE *fp = fopen(gw->filename, "r");
if (!fp) {
printf("Error opening file %s\n", gw->filename);
return;
}
char line[256];
int line_num = 0;
while (fgets(line, sizeof(line), fp)) {
char *trimmed = line;
while (*trimmed == ' ' || *trimmed == '\t' || *trimmed == '\n') trimmed++;
char *end = trimmed + strlen(trimmed) - 1;
while (end > trimmed && (*end == ' ' || *end == '\t' || *end == '\n')) *end-- = '\0';
if (strlen(trimmed) == 0) continue;
line_num++;
switch (line_num) {
case 1: strncpy(gw->props.title, trimmed, 255); break;
case 2: sscanf(trimmed, "%lf", &gw->props.shallst); break;
case 3: sscanf(trimmed, "%lf", &gw->props.deepst); break;
case 4: sscanf(trimmed, "%lf", &gw->props.gw_delay); break;
case 5: sscanf(trimmed, "%lf", &gw->props.alpha_bf); break;
case 6: sscanf(trimmed, "%lf", &gw->props.gwqmn); break;
case 7: sscanf(trimmed, "%lf", &gw->props.gw_revap); break;
case 8: sscanf(trimmed, "%lf", &gw->props.revapmn); break;
case 9: sscanf(trimmed, "%lf", &gw->props.rchrg_dp); break;
case 10: sscanf(trimmed, "%lf", &gw->props.gwht); break;
case 11: sscanf(trimmed, "%lf", &gw->props.gw_spyld); break;
case 12: sscanf(trimmed, "%lf", &gw->props.shallst_n); break;
case 13: sscanf(trimmed, "%lf", &gw->props.gwsolp); break;
case 14: sscanf(trimmed, "%lf", &gw->props.hlife_ngw); break;
case 15: sscanf(trimmed, "%lf", &gw->props.lat_orgn); break;
case 16: sscanf(trimmed, "%lf", &gw->props.lat_orgp); break;
case 17: sscanf(trimmed, "%lf", &gw->props.alpha_bf_d); break;
}
}
fclose(fp);
// Defaults
if (gw->props.deepst == 0.0) gw->props.deepst = 1000.0;
}
void write_gw(GWFile *gw, char *output_filename) {
FILE *fp = fopen(output_filename, "w");
if (!fp) {
printf("Error opening output file %s\n", output_filename);
return;
}
fprintf(fp, "%s\n", gw->props.title);
fprintf(fp, "%.1f\n", gw->props.shallst);
fprintf(fp, "%.1f\n", gw->props.deepst);
fprintf(fp, "%.1f\n", gw->props.gw_delay);
fprintf(fp, "%.3f\n", gw->props.alpha_bf);
fprintf(fp, "%.1f\n", gw->props.gwqmn);
fprintf(fp, "%.2f\n", gw->props.gw_revap);
fprintf(fp, "%.1f\n", gw->props.revapmn);
fprintf(fp, "%.2f\n", gw->props.rchrg_dp);
fprintf(fp, "%.1f\n", gw->props.gwht);
fprintf(fp, "%.3f\n", gw->props.gw_spyld);
fprintf(fp, "%.2f\n", gw->props.shallst_n);
fprintf(fp, "%.2f\n", gw->props.gwsolp);
fprintf(fp, "%.1f\n", gw->props.hlife_ngw);
fprintf(fp, "%.2f\n", gw->props.lat_orgn);
fprintf(fp, "%.2f\n", gw->props.lat_orgp);
fprintf(fp, "%.3f\n", gw->props.alpha_bf_d);
fclose(fp);
}
void print_properties(GWFile *gw) {
printf("TITLE: %s\n", gw->props.title);
printf("SHALLST: %.1f\n", gw->props.shallst);
printf("DEEPST: %.1f\n", gw->props.deepst);
printf("GW_DELAY: %.1f\n", gw->props.gw_delay);
printf("ALPHA_BF: %.3f\n", gw->props.alpha_bf);
printf("GWQMN: %.1f\n", gw->props.gwqmn);
printf("GW_REVAP: %.2f\n", gw->props.gw_revap);
printf("REVAPMN: %.1f\n", gw->props.revapmn);
printf("RCHRG_DP: %.2f\n", gw->props.rchrg_dp);
printf("GWHT: %.1f\n", gw->props.gwht);
printf("GW_SPYLD: %.3f\n", gw->props.gw_spyld);
printf("SHALLST_N: %.2f\n", gw->props.shallst_n);
printf("GWSOLP: %.2f\n", gw->props.gwsolp);
printf("HLIFE_NGW: %.1f\n", gw->props.hlife_ngw);
printf("LAT_ORGN: %.2f\n", gw->props.lat_orgn);
printf("LAT_ORGP: %.2f\n", gw->props.lat_orgp);
printf("ALPHA_BF_D: %.3f\n", gw->props.alpha_bf_d);
}
// Example usage:
// int main() {
// GWFile gw;
// strcpy(gw.filename, "example.gw");
// read_gw(&gw);
// print_properties(&gw);
// write_gw(&gw, "output.gw");
// return 0;
// }