Commit a1cd5126 authored by Purves, Murray's avatar Purves, Murray
Browse files

Refactoring SPE reader to not rely on keyword/line order

parent cadd30e9
Pipeline #16144 passed with stages
in 9 minutes and 9 seconds
......@@ -153,9 +153,6 @@ class RADIX_PUBLIC Spectrum
template <typename data_type>
class RADIX_PUBLIC SpectrumPCFStream
{
private:
data_type mData;
public:
SpectrumPCFStream(data_type container);
......@@ -163,14 +160,14 @@ class RADIX_PUBLIC SpectrumPCFStream
bool write_to(const std::string &file) const;
private:
data_type mData;
}; // class RADIX_PUBLIC SpectrumPCFStream
template <typename data_type>
class RADIX_PUBLIC SpectrumSPEStream
{
private:
data_type mData;
public:
SpectrumSPEStream(data_type container);
......@@ -178,6 +175,21 @@ class RADIX_PUBLIC SpectrumSPEStream
bool write_to(const std::string &file) const;
private:
data_type mData;
void readMeasTim(std::ifstream &stream, float &liveTime, float &totalTime);
void readDateMea(std::ifstream &stream, std::string &dateTime);
void readData(std::ifstream &stream, int &firstChannel, int &totalEntries,
std::vector<float> &countsByChannel);
void readRoi(std::ifstream &stream, std::string &roi);
void readPresets(std::ifstream &stream,
std::vector<std::string> &presetLines);
void readEnerFit(std::ifstream &stream, const int totalEntries,
float &energyCalGain, float &energyCalOffset);
void readMcaCal(std::ifstream &stream, int &calInt,
std::vector<float> mcaCal);
}; // class RADIX_PUBLIC SpectrumSPEStream
} // namespace radix
......
......@@ -34,6 +34,7 @@ bool SpectrumSPEStream<data_type>::read_from(const std::string &file)
// Read through the file
std::string line;
std::vector<std::string> parts;
while (std::getline(stream, line))
{
// Each time we see "$SPEC_ID:" we have a new set of spectrum data
......@@ -47,195 +48,234 @@ bool SpectrumSPEStream<data_type>::read_from(const std::string &file)
std::string id = line;
radix_line(" Reading new spectrum with ID: " << line);
// Next line should be "$MEAS_TIM:" followed by measurement times
std::getline(stream, line);
if (trim_string(line).compare("$MEAS_TIM:") != 0)
{
radix_line(
" Expected to see \"$MEAS_TIM:\" identifier but didn't - "
"returning");
break;
}
// Read measurement times
std::getline(stream, line);
std::vector<std::string> times =
split_string(" ", trim_string(line), true);
radix_line(" times: " << times.size() << " entries");
// Variables used to define a spectrum
float liveTime = 0.f, totalTime = 0.f;
// TODO: Ensure live/total times are in the right order
if (times.size() > 0)
{
radix_line(" " << times[0]);
liveTime = std::stof(times[0]);
}
if (times.size() > 1)
{
radix_line(" " << times[1]);
totalTime = std::stof(times[1]);
}
std::string dateTime = "";
int firstChannel = 0, totalEntries = 0;
std::vector<float> countsByChannel;
std::string roi = "";
std::vector<std::string> presetLines;
float energyCalGain = 0.f, energyCalOffset = 0.f;
int calInt = 0;
std::vector<float> mcaCal;
// Next line should be "$DATE_MEA:" followed by date/time of measurement
std::getline(stream, line);
if (trim_string(line).compare("$DATE_MEA:") != 0)
// Read in keyword-delimited sections
while (std::getline(stream, line))
{
radix_line(
" Expected to see \"$DATE_MEA:\" identifier but didn't - "
"returning");
break;
if (trim_string(line).compare("$MEAS_TIM:") == 0)
{
readMeasTim(stream, liveTime, totalTime);
}
else if (trim_string(line).compare("$DATE_MEA:") == 0)
{
// Read date/time
readDateMea(stream, dateTime);
}
else if (trim_string(line).compare("$DATA:") == 0)
{
// Read data
readData(stream, firstChannel, totalEntries, countsByChannel);
}
else if (trim_string(line).compare("$ROI:") == 0)
{
// Read ROI information
readRoi(stream, roi);
}
else if (trim_string(line).compare("$PRESETS:") == 0)
{
// Read preset lines
readPresets(stream, presetLines);
}
else if (trim_string(line).compare("$ENER_FIT:") == 0)
{
// Read the energy fit
readEnerFit(stream, totalEntries, energyCalGain, energyCalOffset);
}
else if (trim_string(line).compare("$MCA_CAL:") == 0)
{
// Read MCA calibration lines
readMcaCal(stream, calInt, mcaCal);
}
else if (trim_string(line).compare("$ENDRECORD:") == 0)
{
// End of this spectrum - populate SpectrumData object
radix_line(" Adding spectrum...");
mData->addSpectrumData(id, "", "", dateTime, "", liveTime, totalTime,
0.f, energyCalOffset, energyCalGain, 0.f, 0.f,
0.f, 0.f, totalEntries, countsByChannel);
result = true;
break;
}
}
// Read date/time
std::getline(stream, line);
std::string dateTime = trim_string(line);
}
}
// Next line should be "$DATA:" followed by spectrum data
std::getline(stream, line);
if (trim_string(line).compare("$DATA:") != 0)
{
radix_line(
" Expected to see \"$DATA:\" identifier but didn't - "
"returning");
break;
}
std::vector<float> countsByChannel;
// Read data - first line has first entry plus number of additional
// entries
std::getline(stream, line);
std::vector<std::string> parts =
split_string(" ", trim_string(line), true);
if (parts.size() != 2)
{
radix_line(" Expected two entries in first line ("
<< line << ") - returning");
break;
}
countsByChannel.push_back(std::stof(parts[0]));
int totalEntries = std::stoi(parts[1]) + 1;
// Read the rest of the entries
for (int entry = 1; entry < totalEntries; ++entry)
{
std::getline(stream, line);
countsByChannel.push_back(std::stoi(trim_string(line)));
}
radix_line(" Read in " << countsByChannel.size()
<< " channel entries");
return result;
}
// TODO: Work out why there is one extra line in here
std::getline(stream, line);
template <typename data_type>
bool SpectrumSPEStream<data_type>::write_to(const std::string &file) const
{
bool result = false;
// Next line should be "$ROI:" followed by region of interest
std::getline(stream, line);
if (trim_string(line).compare("$ROI:") != 0)
{
radix_line(
" Expected to see \"$ROI:\" identifier but didn't - "
"returning");
break;
}
// Read ROI information
std::getline(stream, line);
std::string roi = trim_string(line);
return result;
}
// Next line should be "$PRESETS:" followed by preset info
std::getline(stream, line);
if (trim_string(line).compare("$PRESETS:") != 0)
{
radix_line(
" Expected to see \"$PRESETS:\" identifier but didn't - "
"returning");
break;
}
// 3 preset lines
std::vector<std::string> presetLines;
for (int i = 0; i < 3; ++i)
{
std::getline(stream, line);
presetLines.push_back(trim_string(line));
}
template <typename data_type>
void SpectrumSPEStream<data_type>::readMeasTim(std::ifstream &stream,
float &liveTime,
float &totalTime)
{
std::string line = "";
// Next line should be "$ENER_FIT:" followed by energy fit
std::getline(stream, line);
if (trim_string(line).compare("$ENER_FIT:") != 0)
{
radix_line(
" Expected to see \"$ENER_FIT:\" identifier but didn't - "
"returning");
break;
}
// Read the energy fit
std::getline(stream, line);
parts.clear();
parts = split_string(" ", trim_string(line), true);
float energyFit1 = 0.f, energyFit2 = 0.f, energyFit3 = 0.f;
if (parts.size() > 0)
{
energyFit1 = stof(parts[0]);
}
if (parts.size() > 1)
{
energyFit2 = stof(parts[1]);
}
if (parts.size() > 2)
{
energyFit3 = stof(parts[2]);
}
// Calculate calibration terms from this
float energyCalGain = energyFit2 / float(totalEntries);
float energyCalOffset =
energyFit1 - ((0.5 / float(totalEntries)) * energyCalGain);
// Read measurement times
std::getline(stream, line);
std::vector<std::string> times = split_string(" ", trim_string(line), true);
radix_line(" times: " << times.size() << " entries");
// Next line should be "$MCA_CAL:" followed by MCA calibration
std::getline(stream, line);
if (trim_string(line).compare("$MCA_CAL:") != 0)
{
radix_line(
" Expected to see \"$MCA_CAL:\" identifier but didn't - "
"returning");
break;
}
// Read MCA calibration lines
std::getline(stream, line);
// TODO: Work out what some of these are
int calInt = std::stoi(trim_string(line));
std::getline(stream, line);
parts.clear();
parts = split_string(" ", trim_string(line), true);
float mcaCal1 = 0.f, mcaCal2 = 0.f, mcaCal3 = 0.f;
if (parts.size() > 0)
{
mcaCal1 = stof(parts[0]);
}
if (parts.size() > 1)
{
mcaCal2 = stof(parts[1]);
}
if (parts.size() > 2)
{
mcaCal3 = stof(parts[2]);
}
// TODO: Ensure live/total times are in the right order
if (times.size() > 0)
{
radix_line(" " << times[0]);
liveTime = std::stof(times[0]);
}
if (times.size() > 1)
{
radix_line(" " << times[1]);
totalTime = std::stof(times[1]);
}
}
// Next line should be "$ENDRECORD:" signifying the end of the record
std::getline(stream, line);
radix_line(" " << line);
template <typename data_type>
void SpectrumSPEStream<data_type>::readDateMea(std::ifstream &stream,
std::string &dateTime)
{
std::string line = "";
// Populate SpectrumData object
radix_line(" Adding spectrum...");
mData->addSpectrumData(id, "", "", dateTime, "", liveTime, totalTime, 0.f,
energyCalOffset, energyCalGain, 0.f, 0.f, 0.f, 0.f,
totalEntries, countsByChannel);
std::getline(stream, line);
dateTime = trim_string(line);
radix_line(" date/time: " << dateTime);
}
result = true;
}
template <typename data_type>
void SpectrumSPEStream<data_type>::readData(std::ifstream &stream,
int &firstChannel,
int &totalEntries,
std::vector<float> &countsByChannel)
{
std::string line = "";
// Read data - first line has channel # of first entry plus number of
// additional entries
std::getline(stream, line);
std::vector<std::string> parts = split_string(" ", trim_string(line), true);
if (parts.size() != 2)
{
radix_line(" Expected two entries in first line (" << line
<< ") - returning");
return;
}
firstChannel = std::stoi(trim_string(parts[0]));
totalEntries = std::stoi(trim_string(parts[1]));
// Read the rest of the entries
for (int entry = 0; entry < totalEntries; ++entry)
{
std::getline(stream, line);
countsByChannel.push_back(std::stoi(trim_string(line)));
}
radix_line(" Read in " << countsByChannel.size() << " channel entries");
}
return result;
template <typename data_type>
void SpectrumSPEStream<data_type>::readRoi(std::ifstream &stream,
std::string &roi)
{
std::string line = "";
std::getline(stream, line);
roi = trim_string(line);
radix_line(" roi: " << roi);
}
template <typename data_type>
bool SpectrumSPEStream<data_type>::write_to(const std::string &file) const
void SpectrumSPEStream<data_type>::readPresets(
std::ifstream &stream, std::vector<std::string> &presetLines)
{
bool result = false;
std::string line = "";
return result;
// 3 preset lines
for (int i = 0; i < 3; ++i)
{
std::getline(stream, line);
presetLines.push_back(trim_string(line));
}
radix_line(" presets:");
radix_block(for (int i = 0; i < presetLines.size();
++i) { radix_line(" " << presetLines[i]); });
}
template <typename data_type>
void SpectrumSPEStream<data_type>::readEnerFit(std::ifstream &stream,
const int totalEntries,
float &energyCalGain,
float &energyCalOffset)
{
std::string line = "";
std::getline(stream, line);
std::vector<std::string> parts = split_string(" ", trim_string(line), true);
float energyFit1 = 0.f, energyFit2 = 0.f, energyFit3 = 0.f;
if (parts.size() > 0)
{
energyFit1 = stof(parts[0]);
}
if (parts.size() > 1)
{
energyFit2 = stof(parts[1]);
}
if (parts.size() > 2)
{
energyFit3 = stof(parts[2]);
}
// Calculate calibration terms from this
energyCalGain = energyFit2 / float(totalEntries);
energyCalOffset = energyFit1 - ((0.5 / float(totalEntries)) * energyCalGain);
radix_line(" energy calibration:");
radix_line(" gain: " << energyCalGain);
radix_line(" offset: " << energyCalOffset);
}
template <typename data_type>
void SpectrumSPEStream<data_type>::readMcaCal(std::ifstream &stream,
int &calInt,
std::vector<float> mcaCal)
{
std::string line = "";
// Read MCA calibration lines
std::getline(stream, line);
// TODO: Work out what some of these are
calInt = std::stoi(trim_string(line));
std::getline(stream, line);
std::vector<std::string> parts = split_string(" ", trim_string(line), true);
for (int i = 0; i < calInt; ++i)
{
if (parts.size() > i)
{
mcaCal.push_back(stof(trim_string(parts[i])));
}
}
radix_line(" MCA calibration: should be " << calInt << " entries");
radix(" ");
radix_block(
for (int i = 0; i < mcaCal.size(); ++i) { radix(mcaCal[i] << " "); });
radix_line(" - " << mcaCal.size() << " found");
}
} // namespace radix
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment