-
Notifications
You must be signed in to change notification settings - Fork 1
/
ConvertFile.cpp
149 lines (122 loc) · 4.38 KB
/
ConvertFile.cpp
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// File : ConvertFile.cpp
// Author : Neil Massey
// Date : 20/11/08
// Purpose : Main function for um to netCDF conversion
#include <iostream>
#include <fstream>
#include <list>
#include "ConvertFile.h"
#include "ReadUMFile.h"
#include "ExtractVariables.h"
#include "Variable.h"
#include "WriteNetCDFFile.h"
#include "VarLevTrans.h"
#include "GlobalAtts.h"
#include "Packing.h"
//*****************************************************************************
bool IsUMFile(std::ifstream& x_infile)
{
// check that the first 6 words of the file make some sense
const int ci_hdrchk_words = 6;
x_infile.seekg(0);
UM_WORD px_hdrchk[ci_hdrchk_words];
x_infile.read((char*)(px_hdrchk), sizeof(UM_WORD) * ci_hdrchk_words);
bool b_valid = true;
/* for (int i=0; i<6; i++)
std::cout << px_hdrchk[i] << " ";
std::cout << std::endl;*/
b_valid &= (px_hdrchk[0] == -32768);
b_valid &= (px_hdrchk[1] >= 1 && px_hdrchk[1] <= 4 );
b_valid &= (px_hdrchk[2] >= 1 && px_hdrchk[2] <= 6 );
b_valid &= (px_hdrchk[3] >= 0 && px_hdrchk[3] <= 105 );
b_valid &= (px_hdrchk[4] >= 1 && px_hdrchk[4] <= 10 );
// b_valid &= (px_hdrchk[5] >= 0 && px_hdrchk[5] <= 10000);
return b_valid;
}
//*****************************************************************************
int ConvertFile(std::string s_input_file_name, std::string s_output_file_name,
std::string s_xml_file_name, std::string s_pack_file_name,
std::string s_gatts_file_name)
{
// try to open the file for reading
int i_ret = 0;
std::ifstream x_infile;
x_infile.open(s_input_file_name.c_str(), std::ios::in|std::ios_base::binary);
if (!x_infile)
{
std::cerr << "Error: Input file: " << s_input_file_name << " could not be opened." << std::endl;
i_ret = 1;
}
// check that the file is a UM field file by checking the headers
if (i_ret != 1 && !IsUMFile(x_infile))
{
std::cerr << "Error: Input file: " << s_input_file_name << " is not a UM file." << std::endl;
i_ret = 1;
}
if (i_ret != 1)
{
// read headers
UM_WORD *px_fixhdr, *px_pphdrs, *px_intc, *px_realc;
UM_WORD *px_levc, *px_rowc, *px_colc, *px_fieldc;
ReadHdrs(x_infile,
px_fixhdr, px_pphdrs, px_intc, px_realc,
px_levc, px_rowc, px_colc, px_fieldc);
// get the reference time
MTime x_ref_time(&(px_fixhdr[20]), px_fixhdr[7]);
// read the data - note that this will have to be converted to it's
// actual type by checking the pphdr
UM_WORD* px_data = ReadData(x_infile, px_fixhdr, px_pphdrs);
// check that some data was actually read.
if (px_data == NULL)
{
std::cerr << "Error: Input file: " << s_input_file_name << " contains no data." << std::endl;
i_ret = 1;
}
// create the lists for storing the info about the file
std::list<Variable> x_var_list;
if (i_ret != 1)
ExtractVarFields(px_fixhdr, px_pphdrs, px_data, x_var_list);
// read the xml file definition of level and variable names and attributes
VarLevTrans x_var_lev_trans(s_xml_file_name);
if (i_ret != 1 && !x_var_lev_trans.LoadAttributes())
{
std::cerr << "Error: XML file: " << s_xml_file_name << " error in XML or file could not be opened." << std::endl;
i_ret = 1;
}
// read the xml file for the packing details
Packing x_packing(s_pack_file_name);
if (i_ret != 1 && !x_packing.LoadAttributes())
{
std::cerr << "Error: XML file: " << s_pack_file_name << " error in XML or file could not be opened." << std::endl;
i_ret = 1;
}
// Pack the variables
x_packing.PackVariables(x_var_list);
GlobalAtts x_gatts;
if (i_ret != 1)
{
if (s_gatts_file_name != "")
if (!x_gatts.LoadAttributes(s_gatts_file_name))
{
std::cerr << "Error: Failed to load global attributes file: " << s_gatts_file_name << std::endl;
i_ret = 1;
}
}
// write out the netCDF file - we have all the necessary info now
if (i_ret != 1)
i_ret = WriteNetCDFFile(s_output_file_name, x_var_list, x_ref_time,
x_var_lev_trans, x_gatts);
if (i_ret == 1)
std::cerr << "Error: Output file could not be written." << std::endl;
// clean up headers
CleanHdrs(px_fixhdr, px_pphdrs, px_intc, px_realc,
px_levc, px_rowc, px_colc, px_fieldc);
CleanData(px_data);
// close input file
x_infile.close();
if (i_ret != 1)
std::cout << "Converted file: " << s_input_file_name << " to: "
<< s_output_file_name << std::endl;
}
return i_ret;
}