WSL/SLF GitLab Repository

libsmet.cc 38.8 KB
Newer Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
		julian_start = i_julian_start;
		julian_end = i_julian_end;

		read(vec_data);

		julian_interval = false;
	}
}

void SMETReader::read(std::vector<std::string>& vec_timestamp, std::vector<double>& vec_data)
{
1012
	if (!timestamp_present)
1013
		throw SMETException("Requesting to read timestamp when there is none present in \""+filename+"\"", SMET_AT);
1014
1015
1016

	ifstream fin;
	fin.clear();
1017
	if (!SMETCommon::fileExists(filename)) throw SMETException(filename, AT); //prevent invalid filenames
1018
	errno = 0;
1019
	fin.open (filename.c_str(), ios::in|ios::binary); //ascii mode messes up pointer code on windows (automatic eol translation)
1020
	if (fin.fail()) {
1021
		ostringstream ss;
1022
		ss << "Error opening file \"" << filename << "\" for reading, possible reason: " << strerror(errno);
1023
1024
		throw SMETException(ss.str(), SMET_AT);
	}
1025
1026

	try {
1027
		streampos fpointer = static_cast<streampos>(-1);
1028
		if (timestamp_interval && timestamp_present){
1029
			fpointer = indexer.getIndex(timestamp_start);
1030
		} else if (julian_interval && julian_present){
1031
			fpointer = indexer.getIndex(julian_start);
1032
		}
1033

1034
1035
		if(fpointer!=static_cast<streampos>(-1))
			fin.seekg(fpointer); //a previous pointer was found, jump to it
1036
		else {
1037
1038
1039
1040
1041
1042
1043
1044
			if(data_start_fpointer!=static_cast<streampos>(-1))
				fin.seekg(data_start_fpointer); //nothing was found, jump to data start position in the file
			else { //the data section was itself empty (not even containg \n)
				cleanup(fin);
				return;
			}
		}

1045
1046
		if (fin.fail() || fin.bad())
			fin.seekg(data_start_fpointer);
1047

1048
1049
1050
		if (isAscii)
			read_data_ascii(fin, vec_timestamp, vec_data);
		else
1051
			throw SMETException("Binary SMET file \""+filename+"\" has no field timestamp, only julian date", SMET_AT);
1052
1053
	} catch(...) {
		cleanup(fin);
1054
		throw;
1055
1056
1057
1058
1059
1060
1061
	}

	cleanup(fin);
}

void SMETReader::read(std::vector<double>& vec_data)
{
1062
	if (timestamp_present)
1063
		throw SMETException("Requesting not to read timestamp when there is one present in \""+filename+"\"", SMET_AT);
1064

1065
	ios_base::openmode mode = ios::in|ios::binary; //read as binary to avoid eol mess
1066
1067

	ifstream fin;
1068
	if (!SMETCommon::fileExists(filename)) throw SMETException(filename, AT); //prevent invalid filenames
1069
	errno = 0;
1070
	fin.open (filename.c_str(), mode);
1071
	if (fin.fail()) {
1072
		ostringstream ss;
1073
		ss << "Error opening file \"" << filename << "\" for reading, possible reason: " << strerror(errno);
1074
1075
		throw SMETException(ss.str(), SMET_AT);
	}
1076

1077
	try {
1078
		streampos fpointer = static_cast<streampos>(-1);
1079
		if (julian_interval && julian_present){
1080
			fpointer = indexer.getIndex(julian_start);
1081
		}
1082
1083
		if(fpointer!=static_cast<streampos>(-1))
			fin.seekg(fpointer); //a previous pointer was found, jump to it
1084
		else {
1085
1086
1087
1088
1089
1090
			if(data_start_fpointer!=static_cast<streampos>(-1))
				fin.seekg(data_start_fpointer); //nothing was found, jump to data start position in the file
			else { //the data section was itself empty (not even containg \n)
				cleanup(fin);
				return;
			}
1091
		}
1092
1093
1094

		if (fin.fail() || fin.bad())
			fin.seekg(data_start_fpointer);
1095

1096
1097
		if (isAscii) {
			vector<string> tmp_vec;
1098
			read_data_ascii(fin, tmp_vec, vec_data);
1099
		} else {
1100
			read_data_binary(fin, vec_data);
1101
		}
1102
1103
	} catch(...) {
		cleanup(fin);
1104
		throw;
1105
1106
1107
1108
1109
1110
	}

	cleanup(fin);
}

void SMETReader::read_data_ascii(std::ifstream& fin, std::vector<std::string>& vec_timestamp, std::vector<double>& vec_data)
1111
{
1112
	const size_t nr_of_data_fields = (timestamp_present)? nr_of_fields+1 : nr_of_fields;
1113
1114
	vector<string> tmp_vec;
	string line;
1115
	size_t linenr = 0;
1116
	streampos current_fpointer = static_cast<streampos>(-1);
1117

1118
	while (!fin.eof()){
1119
		const streampos tmp_fpointer = fin.tellg();
1120
1121
		line.clear();
		getline(fin, line, eoln);
1122
		linenr++;
1123
1124
		SMETCommon::stripComments(line);
		SMETCommon::trim(line);
1125
		if (line.empty()) continue; //Pure comment lines and empty lines are ignored
1126
1127

		if (SMETCommon::readLineToVec(line, tmp_vec) == nr_of_data_fields){
1128
1129
1130
			try {
				size_t shift = 0;
				if (julian_interval && julian_present){
1131
					const double current_julian = SMETCommon::convert_to_double(tmp_vec[julian_field]);
1132
					if( (linenr % streampos_every_n_lines)==0 && (current_fpointer != static_cast<streampos>(-1)) )
1133
						indexer.setIndex(current_julian, tmp_fpointer);
1134
1135
1136
1137
1138
					if (current_julian < julian_start)
						continue; //skip lines that don't hold the dates we're interested in
					else if (current_julian > julian_end)
						break; //skip the rest of the file
				}
1139

1140
				if (timestamp_interval && timestamp_present){
1141
					const string& current_timestamp = tmp_vec[timestamp_field];
1142
					if( (linenr % streampos_every_n_lines)==0 && (tmp_fpointer != static_cast<streampos>(-1)) )
1143
						indexer.setIndex(current_timestamp, tmp_fpointer);
1144
1145
1146
1147
1148
					if (current_timestamp < timestamp_start)
						continue; //skip lines that don't hold the dates we're interested in
					else if (current_timestamp > timestamp_end)
						break; //skip the rest of the file
				}
1149

1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
				for (size_t ii=0; ii<tmp_vec.size(); ii++){
					if (timestamp_present && (ii == timestamp_field)) {
						vec_timestamp.push_back(tmp_vec[ii]);
						shift = 1;
					} else {
						double tmp = SMETCommon::convert_to_double(tmp_vec[ii]);
						if ((mksa) && (tmp != nodata_value)){
							tmp *= vec_multiplier[ii-shift];
							tmp += vec_offset[ii-shift];
						}
						vec_data.push_back(tmp);
1161
1162
					}
				}
1163
1164
				current_fpointer = tmp_fpointer;
			} catch(SMETException&) {
1165
				cerr << "Error reading file \"" << filename << "\" at line \"" << line << "\"" << endl;
1166
				throw;
1167
			}
1168
		} else {
1169
			std::ostringstream ss;
1170
			ss << "File \'" << filename << "\' declares " << nr_of_data_fields << " columns ";
1171
			ss << "but this does not match the following line:\n" << line << "\n";
1172
			throw SMETException(ss.str(), SMET_AT);
1173
1174
1175
		}
	}

1176
	if (current_fpointer != static_cast<streampos>(-1)){
1177
		if (timestamp_interval && timestamp_present)
1178
			indexer.setIndex(timestamp_end, current_fpointer);
1179
		else if (julian_interval && julian_present)
1180
			indexer.setIndex(julian_end, current_fpointer);
1181
1182
1183
1184
1185
	}
}

void SMETReader::read_data_binary(std::ifstream& fin, std::vector<double>& vec_data)
{
1186
	size_t linenr = 0;
1187
	streampos current_fpointer = static_cast<streampos>(-1);
1188
	while (!fin.eof()){
1189
		const streampos tmp_fpointer = fin.tellg();
1190
1191
1192
1193
1194
1195
1196
1197
		double julian = -1.0;
		for (size_t ii=0; ii<nr_of_fields; ii++){
			if (julian_present && (ii == julian_field)){
				fin.read(reinterpret_cast < char * > (&julian), sizeof(double));
				vec_data.push_back(julian);
			} else {
				float tmpval;
				fin.read(reinterpret_cast < char * > (&tmpval), sizeof(float));
1198
				const double val = (double)tmpval;
1199
1200
1201

				vec_data.push_back(val);
			}
1202
			linenr++;
1203
1204
1205
1206
1207
1208
1209
1210
1211

			if (mksa){
				double& tmp = vec_data.back();
				if (tmp != nodata_value){
					tmp *= vec_multiplier[ii];
					tmp += vec_offset[ii];
				}
			}
		}
1212

1213
		if (julian_present && julian_interval){
1214
			if( (linenr % streampos_every_n_lines)==0 && (tmp_fpointer != static_cast<streampos>(-1)) )
1215
				indexer.setIndex(julian, tmp_fpointer);
1216
1217
1218
1219
			if ((julian < julian_start) || (julian > julian_end)){
				for (size_t ii=0; ii<nr_of_fields; ii++){
					vec_data.pop_back();
				}
1220
1221
1222
1223

				if (julian > julian_end) break; //skip the rest of the file
			} else {//we have a valid date
				current_fpointer = tmp_fpointer;
1224
1225
1226
1227
1228
1229
			}
		}

		char c;
		fin.read(&c, sizeof(char));
		if (c != '\n')
1230
			throw SMETException("Corrupted data in section [DATA] of binary SMET file \""+filename+"\"", SMET_AT);
1231
	}
1232

1233
	if (current_fpointer != static_cast<streampos>(-1)){
1234
		if (julian_interval && julian_present)
1235
			indexer.setIndex(julian_end, current_fpointer);
1236
	}
1237
1238
1239
1240
}

double SMETReader::get_header_doublevalue(const std::string& key) const
{
1241
	const map<string,string>::const_iterator it = header.find(key);
1242
1243
	if (it != header.end())
		return SMETCommon::convert_to_double(it->second);
1244

1245
1246
1247
	return nodata_value;
}

1248
1249
int SMETReader::get_header_intvalue(const std::string& key) const
{
1250
	const map<string,string>::const_iterator it = header.find(key);
1251
1252
1253
	if (it != header.end())
		return SMETCommon::convert_to_int(it->second);

1254
	return (int)floor(nodata_value + 0.1);
1255
1256
}

1257
1258
std::string SMETReader::get_header_value(const std::string& key) const
{
1259
	const map<string,string>::const_iterator it = header.find(key);
1260
1261
	if (it != header.end())
		return it->second;
1262

1263
	return std::string();
1264
1265
1266
1267
1268
1269
1270
}

bool SMETReader::contains_timestamp() const
{
	return timestamp_present;
}

1271
1272
1273
1274
1275
std::string SMETReader::get_filename() const
{
	return filename;
}

1276
1277
} //end namespace
For faster browsing, not all history is shown. View entire blame