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

WIP Initial SPE reader. Need to work out exactly which parameters are equivalent to which

parent f61e8b8f
Pipeline #16115 passed with stages
in 8 minutes and 41 seconds
......@@ -219,7 +219,8 @@ void Spectrum::setSrsi(short srsi) { mSrsi = srsi; }
int Spectrum::spectrumDataCount() { return mSpectrumData.size(); }
void Spectrum::spectrumData(int i, std::string &buffer, std::string &dateTime,
void Spectrum::spectrumData(int i, std::string &title, std::string &source,
std::string &description, std::string &dateTime,
std::string &tag, float &liveTime, float &totalTime,
float &energyCalOffset, float &energyCalGain,
float &energyCalQuadraticTerm,
......@@ -232,7 +233,9 @@ void Spectrum::spectrumData(int i, std::string &buffer, std::string &dateTime,
{
size_t i_ = size_t(i);
SpectrumData spectrum = mSpectrumData[i];
buffer = spectrum.buffer;
title = spectrum.title;
source = spectrum.source;
description = spectrum.description;
dateTime = spectrum.dateTime;
tag = spectrum.tag;
liveTime = spectrum.liveTime;
......@@ -250,14 +253,17 @@ void Spectrum::spectrumData(int i, std::string &buffer, std::string &dateTime,
}
void Spectrum::addSpectrumData(
std::string buffer, std::string dateTime, std::string tag, float liveTime,
float totalTime, float energyCalOffset, float energyCalGain,
float energyCalQuadraticTerm, float energyCalCubicTerm,
float energyCalLowEnergyTerm, float occupancyFlag, float totalNeutronCount,
int numberOfChannels, std::vector<float> countsByChannel)
std::string title, std::string source, std::string description,
std::string dateTime, std::string tag, float liveTime, float totalTime,
float energyCalOffset, float energyCalGain, float energyCalQuadraticTerm,
float energyCalCubicTerm, float energyCalLowEnergyTerm, float occupancyFlag,
float totalNeutronCount, int numberOfChannels,
std::vector<float> countsByChannel)
{
SpectrumData spectrumData;
spectrumData.buffer = buffer;
spectrumData.title = title;
spectrumData.source = source;
spectrumData.description = description;
spectrumData.dateTime = dateTime;
spectrumData.tag = tag;
spectrumData.liveTime = liveTime;
......
......@@ -17,7 +17,7 @@ class RADIX_PUBLIC Spectrum
struct SpectrumData
{
std::string buffer, dateTime, tag;
std::string title, source, description, dateTime, tag;
float liveTime, totalTime, energyCalOffset, energyCalGain,
energyCalQuadraticTerm, energyCalCubicTerm, energyCalLowEnergyTerm,
occupancyFlag, totalNeutronCount;
......@@ -88,14 +88,16 @@ class RADIX_PUBLIC Spectrum
void setSrsi(short srsi);
int spectrumDataCount();
void spectrumData(int i, std::string &buffer, std::string &dateTime,
void spectrumData(int i, std::string &title, std::string &source,
std::string &description, std::string &dateTime,
std::string &tag, float &liveTime, float &totalTime,
float &energyCalOffset, float &energyCalGain,
float &energyCalQuadraticTerm, float &energyCalCubicTerm,
float &energyCalLowEnergyTerm, float &occupancyFlag,
float &totalNeutronCount, int &numberOfChannels,
std::vector<float> countsByChannel);
void addSpectrumData(std::string buffer, std::string dateTime,
void addSpectrumData(std::string title, std::string source,
std::string description, std::string dateTime,
std::string tag, float liveTime, float totalTime,
float energyCalOffset, float energyCalGain,
float energyCalQuadraticTerm, float energyCalCubicTerm,
......
......@@ -194,63 +194,81 @@ bool SpectrumPCFStream<data_type>::read_from(const std::string &file)
// Buffer
std::string buffer = stream.readString(180);
radix_line(" buffer: " << buffer);
// TODO: Split buffer into title/desc/source
// Split buffer into title/desc/source
char delim = 255;
std::string title = "", description = "", source = "";
if (buffer[0] == delim)
{
// Using a delimiter character
radix_line(" Splitting using delimiter (" << delim << ")...");
std::vector<std::string> bufferItems =
split_string(std::string(1, delim), trim_string(buffer));
if (bufferItems.size() > 0)
{
title = bufferItems[0];
}
if (bufferItems.size() > 1)
{
description = bufferItems[1];
}
if (bufferItems.size() > 2)
{
source = bufferItems[2];
}
}
else
{
// Splitting evenly (60 characters each)
radix_line(" Splitting evenly (60 chars per item)...");
title = buffer.substr(0, 59);
description = buffer.substr(60, 119);
source = buffer.substr(120, 179);
}
radix_line(" title: " << title);
radix_line(" description: " << description);
radix_line(" source: " << source);
// Date/time
std::string dateTime = stream.readString(23);
radix_line(" date/time: " << dateTime);
// Tag
std::string tag = stream.readString(1);
radix_line(" tag: " << tag);
// Live time
float liveTime = stream.readFloat();
radix_line(" live time: " << liveTime);
// Total time
float totalTime = stream.readFloat();
radix_line(" total time: " << totalTime);
// Three unused values
stream.readFloat();
stream.readFloat();
stream.readFloat();
// Energy calibration offset
float energyCalOffset = stream.readFloat();
radix_line(" energy calibration offset:" << energyCalOffset);
// Energy calibration gain
float energyCalGain = stream.readFloat();
radix_line(" energy calibration gain:" << energyCalGain);
// Energy calibration quadratic term
float energyCalQuadraticTerm = stream.readFloat();
radix_line(
" energy calibration quadratic term:" << energyCalQuadraticTerm);
// Energy calibration cubic term
float energyCalCubicTerm = stream.readFloat();
radix_line(" energy calibration cubic term:" << energyCalCubicTerm);
// Energy calibration quadratic term
float energyCalLowEnergyTerm = stream.readFloat();
radix_line(
" energy calibration quadratic term:" << energyCalLowEnergyTerm);
// Occupancy flag
float occupancyFlag = stream.readFloat();
radix_line(" occupancy flag:" << occupancyFlag);
// Total neutron count
float totalNeutronCount = stream.readFloat();
radix_line(" total neutron count:" << totalNeutronCount);
// Number of channels in spectrum
int numberOfChannels = stream.readInt();
radix_line(" number of channels in spectrum:" << numberOfChannels);
// Read channel data
radix_line(" Read spectral record header; reading data from "
<< numberOfChannels << " channels...");
......@@ -260,7 +278,7 @@ bool SpectrumPCFStream<data_type>::read_from(const std::string &file)
float counts = stream.readFloat();
countsByChannel.push_back(counts);
}
radix_line(" " << countsByChannel.size() << " channels read");
// Get the max number of channels available and skip to the end
// (the rest after numberOfChannels will be junk)
int cMaxBytes = 64 * (nrps - 1) * 4;
......@@ -272,16 +290,18 @@ bool SpectrumPCFStream<data_type>::read_from(const std::string &file)
// Build a SpectrumData object with this data and add it to the list
radix_line(" Adding spectrum...");
mData->addSpectrumData(
buffer, dateTime, tag, liveTime, totalTime, energyCalOffset,
energyCalGain, energyCalQuadraticTerm, energyCalCubicTerm,
energyCalLowEnergyTerm, occupancyFlag, totalNeutronCount,
numberOfChannels, countsByChannel);
title, source, description, dateTime, tag, liveTime, totalTime,
energyCalOffset, energyCalGain, energyCalQuadraticTerm,
energyCalCubicTerm, energyCalLowEnergyTerm, occupancyFlag,
totalNeutronCount, numberOfChannels, countsByChannel);
// Peek into next bit to check EOF
stream.peek();
}
radix_line(" All spectral data read");
radix_line("PCF file read complete and successful");
radix_line("PCF file read complete and successful. "
<< mData->spectrumDataCount() << " spectra read");
result = true;
return result;
}
......
#ifndef RADIX_RADIXIO_SPECTRUMSPESTREAM_HH_
#define RADIX_RADIXIO_SPECTRUMSPESTREAM_HH_
#include <fstream>
#include <string>
#include "radixbug/bug.hh"
#include "radixcore/stringfunctions.hh"
#include "radixcore/visibility.hh"
#include "radixio/spectrum.hh"
......@@ -19,6 +22,208 @@ bool SpectrumSPEStream<data_type>::read_from(const std::string &file)
{
bool result = false;
radix_line("Reading data from SPE file: " << file);
// Open a stream of the file
std::ifstream stream(file.c_str());
if (stream.is_open() == false)
{
radix_line("Failed to open file - returning false");
return result;
}
// Read through the file
std::string line;
while (std::getline(stream, line))
{
// Each time we see "$SPEC_ID:" we have a new set of spectrum data
if (trim_string(line) == "$SPEC_ID:")
{
// Reset the error flag while we read a new spectrum
result = false;
// Next line is the ID
std::getline(stream, line);
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");
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]);
}
// Next line should be "$DATE_MEA:" followed by date/time of measurement
std::getline(stream, line);
if (trim_string(line).compare("$DATE_MEA:") != 0)
{
radix_line(
" Expected to see \"$DATE_MEA:\" identifier but didn't - "
"returning");
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");
// TODO: Work out why there is one extra line in here
std::getline(stream, line);
// 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);
// 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));
}
// 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);
// TODO: Work out what these calibrations refer to
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]);
}
// 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]);
}
// Next line should be "$ENDRECORD:" signifying the end of the record
std::getline(stream, line);
radix_line(" " << line);
// Populate SpectrumData object
radix_line(" Adding spectrum...");
mData->addSpectrumData(id, "", "", dateTime, "", liveTime, totalTime, 0.f,
energyFit1, energyFit2, energyFit3, 0.f, 0.f, 0.f,
totalEntries, countsByChannel);
result = true;
}
}
return result;
}
......
......@@ -31,19 +31,20 @@ TEST(RadixIO, SpectrumFromPCF)
// ASSERT_TRUE(stream.write_to(testPCFFile));
//}
// TEST(RadixIO, SpectrumFromSPE)
//{
// std::string testSPEFile =
// radix::to_native_path(std::string(dirname(__FILE__) + "data/235F.spe"));
TEST(RadixIO, SpectrumFromSPE)
{
std::string testSPEFile =
radix::to_native_path(std::string(dirname(__FILE__) + "/data/235F.spe"));
// Spectrum::SP testSpectrum = std::make_shared<Spectrum>();
Spectrum::SP testSpectrum = std::make_shared<Spectrum>();
// // Load the spectrum
// SpectrumSPEStream<Spectrum::SP> stream(testSpectrum);
// ASSERT_TRUE(stream.read_from(testSPEFile));
// Load the spectrum
SpectrumSPEStream<Spectrum::SP> stream(testSpectrum);
ASSERT_TRUE(stream.read_from(testSPEFile));
// // Test the spectrum contents
//}
// Test the spectrum contents
EXPECT_EQ(30, testSpectrum->spectrumDataCount());
}
// TEST(RadixIO, SpectrumToSPE)
//{
......
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