diff --git a/Source/Data/CMakeLists.txt b/Source/Data/CMakeLists.txt index da85d0d0c..52fd90b83 100644 --- a/Source/Data/CMakeLists.txt +++ b/Source/Data/CMakeLists.txt @@ -36,6 +36,7 @@ set (DATA_HEADERFILES EventAnalysis/KTSparseWaterfallCandidateData.hh EventAnalysis/KTSpectrumCollectionData.hh EventAnalysis/KTWaterfallCandidateData.hh + Time/KTArbitraryMetadata.hh Time/KTDigitizerTestData.hh Time/KTEggHeader.hh Time/KTProcSummary.hh @@ -101,6 +102,7 @@ set (DATA_SOURCEFILES EventAnalysis/KTSparseWaterfallCandidateData.cc EventAnalysis/KTSpectrumCollectionData.cc EventAnalysis/KTWaterfallCandidateData.cc + Time/KTArbitraryMetadata.cc Time/KTDigitizerTestData.cc Time/KTEggHeader.cc Time/KTProcSummary.cc diff --git a/Source/Data/Time/KTArbitraryMetadata.cc b/Source/Data/Time/KTArbitraryMetadata.cc new file mode 100644 index 000000000..ad7807aaf --- /dev/null +++ b/Source/Data/Time/KTArbitraryMetadata.cc @@ -0,0 +1,25 @@ +/* + * KTArbitraryMetadata.cc + * + * Created on: Sept 20, 2021 + * Author: N.S. Oblath + */ + +#include "KTArbitraryMetadata.hh" + +namespace Katydid +{ + const std::string KTArbitraryMetadata::sName("arbitrary-metadata"); + + KTArbitraryMetadata::KTArbitraryMetadata() : + KTExtensibleData< KTArbitraryMetadata >(), + fMetadata(nullptr) + { + } + + KTArbitraryMetadata::~KTArbitraryMetadata() + { + delete fMetadata; + } + +} /* namespace Katydid */ diff --git a/Source/Data/Time/KTArbitraryMetadata.hh b/Source/Data/Time/KTArbitraryMetadata.hh new file mode 100644 index 000000000..ee4431680 --- /dev/null +++ b/Source/Data/Time/KTArbitraryMetadata.hh @@ -0,0 +1,40 @@ +/* + * KTArbitraryMetadata.hh + * + * Created on: Sept 20, 2021 + * Author: N.S. Oblath + */ + +#ifndef KTARBITRARY_METADATA_HH_ +#define KTARBITRARY_METADATA_HH_ + +#include "KTData.hh" + +#include "param.hh" + + +namespace Katydid +{ + class KTArbitraryMetadata : public Nymph::KTExtensibleData< KTArbitraryMetadata > + { + public: + KTArbitraryMetadata(); + virtual ~KTArbitraryMetadata(); + + void SetMetadata( scarab::param* metadata ); + MEMBERVARIABLE_NOSET(scarab::param*, Metadata); + + public: + static const std::string sName; + + }; + + inline void KTArbitraryMetadata::SetMetadata( scarab::param* metadata ) + { + delete fMetadata; + fMetadata = metadata; + return; + } + +} /* namespace Katydid */ +#endif /* KTARBITRARY_METADATA_HH_ */ diff --git a/Source/Data/Time/KTEggHeader.cc b/Source/Data/Time/KTEggHeader.cc index 37a8e98fb..600c5b244 100644 --- a/Source/Data/Time/KTEggHeader.cc +++ b/Source/Data/Time/KTEggHeader.cc @@ -85,6 +85,7 @@ namespace Katydid KTEggHeader::KTEggHeader() : KTExtensibleData< KTEggHeader >(), fFilename(), + fMetadataFilename(), fAcquisitionMode(1), fRunDuration(0), fAcquisitionRate(0), @@ -99,6 +100,7 @@ namespace Katydid KTEggHeader::KTEggHeader(const KTEggHeader& orig) : fFilename(orig.fFilename), + fMetadataFilename(orig.fMetadataFilename), fAcquisitionMode(orig.fAcquisitionMode), fRunDuration(orig.fRunDuration), fAcquisitionRate(orig.fAcquisitionRate), @@ -122,6 +124,7 @@ namespace Katydid KTEggHeader& KTEggHeader::operator=(const KTEggHeader& rhs) { fFilename = rhs.fFilename; + fMetadataFilename = rhs.fMetadataFilename; fAcquisitionMode = rhs.fAcquisitionMode; fRunDuration = rhs.fRunDuration; fAcquisitionRate = rhs.fAcquisitionRate; @@ -182,6 +185,7 @@ namespace Katydid { out << "File header:\n" << "\tFilename: " << header.GetFilename() << '\n' + << "\tMetadata Filename: " << header.GetMetadataFilename() << '\n' << "\tAcquisition Mode: " << header.GetAcquisitionMode() << '\n' << "\tNumber of Channels: " << header.GetNChannels() << '\n' << "\tRun Duration: " << header.GetRunDuration() << " ms\n" diff --git a/Source/Data/Time/KTEggHeader.hh b/Source/Data/Time/KTEggHeader.hh index 2bd0ca9c0..4e3f6ed21 100644 --- a/Source/Data/Time/KTEggHeader.hh +++ b/Source/Data/Time/KTEggHeader.hh @@ -64,6 +64,7 @@ namespace Katydid KTEggHeader& operator=(const KTEggHeader& rhs); MEMBERVARIABLEREF(std::string, Filename); + MEMBERVARIABLEREF(std::string, MetadataFilename); MEMBERVARIABLE(unsigned, AcquisitionMode); MEMBERVARIABLE(unsigned, RunDuration); /// in ms MEMBERVARIABLE(double, AcquisitionRate); /// in Hz diff --git a/Source/IO/TerminalWriter/KTTerminalTypeWriterTime.cc b/Source/IO/TerminalWriter/KTTerminalTypeWriterTime.cc index b2adc093b..2873c2616 100644 --- a/Source/IO/TerminalWriter/KTTerminalTypeWriterTime.cc +++ b/Source/IO/TerminalWriter/KTTerminalTypeWriterTime.cc @@ -7,6 +7,7 @@ #include "KTTerminalTypeWriterTime.hh" +#include "KTArbitraryMetadata.hh" #include "KTDigitizerTestData.hh" #include "KTEggHeader.hh" #include "KTTIFactory.hh" @@ -43,6 +44,7 @@ namespace Katydid void KTTerminalTypeWriterTime::RegisterSlots() { fWriter->RegisterSlot("header", this, &KTTerminalTypeWriterTime::WriteEggHeader); + fWriter->RegisterSlot("metadata", this, &KTTerminalTypeWriterTime::WriteArbitraryMetadata); fWriter->RegisterSlot("ts", this, &KTTerminalTypeWriterTime::WriteTimeSeriesData); fWriter->RegisterSlot("dig-test", this, &KTTerminalTypeWriterTime::WriteDigitizerTestData); fWriter->RegisterSlot("summary", this, &KTTerminalTypeWriterTime::WriteProcSummary); @@ -64,6 +66,22 @@ namespace Katydid } + void KTTerminalTypeWriterTime::WriteArbitraryMetadata(Nymph::KTDataPtr data) + { + if (! data) return; + + scarab::param* metadata = data->Of< KTArbitraryMetadata >().GetMetadata(); + if (metadata == nullptr) + { + KTPROG(termlog, "Metadata is empty"); + return; + } + + KTPROG(termlog, "Arbitrary Metadata:\n" << *metadata); + return; + } + + //***************** // Time Series Data //***************** diff --git a/Source/IO/TerminalWriter/KTTerminalTypeWriterTime.hh b/Source/IO/TerminalWriter/KTTerminalTypeWriterTime.hh index dc970bc70..4c7c4fa31 100644 --- a/Source/IO/TerminalWriter/KTTerminalTypeWriterTime.hh +++ b/Source/IO/TerminalWriter/KTTerminalTypeWriterTime.hh @@ -27,6 +27,7 @@ namespace Katydid public: void WriteEggHeader(Nymph::KTDataPtr data); + void WriteArbitraryMetadata(Nymph::KTDataPtr data); void WriteTimeSeriesData(Nymph::KTDataPtr data); void WriteDigitizerTestData(Nymph::KTDataPtr data); diff --git a/Source/Time/KTEgg1Reader.cc b/Source/Time/KTEgg1Reader.cc index 9d1f42e7d..d0b1f9907 100644 --- a/Source/Time/KTEgg1Reader.cc +++ b/Source/Time/KTEgg1Reader.cc @@ -67,12 +67,12 @@ namespace Katydid { KTWARN(eggreadlog, "Egg1 reader is only setup to handle a single file; multiple files have been specified and all but the first one will be skipped"); } - KTINFO(eggreadlog, "Opening egg file <" << filenames[0] << ">") - fEggStream.open(filenames[0].c_str(), ifstream::in|ifstream::binary); + KTINFO(eggreadlog, "Opening egg file <" << filenames[0].first << ">") + fEggStream.open(filenames[0].first.c_str(), ifstream::in|ifstream::binary); if (! fEggStream.is_open()) { - KTERROR(eggreadlog, "Egg filestream did not open (file: " << filenames[0] << ")"); + KTERROR(eggreadlog, "Egg filestream did not open (file: " << filenames[0].first << ")"); return Nymph::KTDataPtr(); } @@ -223,7 +223,8 @@ namespace Katydid Nymph::KTDataPtr eggHeaderPtr(new Nymph::KTData()); KTEggHeader& eggHeader = eggHeaderPtr->Of< KTEggHeader >(); - eggHeader.SetFilename(filenames[0].native()); + eggHeader.SetFilename(filenames[0].first.native()); + eggHeader.SetMetadataFilename(filenames[0].second.native()); eggHeader.SetAcquisitionMode(1); eggHeader.SetRunDuration(fHeaderInfo.fRunLength * 1000); // conversion from s to ms eggHeader.SetAcquisitionRate(fHeaderInfo.fSampleRate * fHeaderInfo.fHertzPerSampleRateUnit); diff --git a/Source/Time/KTEgg2Reader.cc b/Source/Time/KTEgg2Reader.cc index f1cd4b079..3b97a9e42 100644 --- a/Source/Time/KTEgg2Reader.cc +++ b/Source/Time/KTEgg2Reader.cc @@ -103,10 +103,10 @@ namespace Katydid { KTWARN(eggreadlog, "Egg2 reader is only setup to handle a single file; multiple files have been specified and all but the first one will be skipped"); } - KTINFO(eggreadlog, "Opening egg file <" << filenames[0] << ">"); + KTINFO(eggreadlog, "Opening egg file <" << filenames[0].first << ">"); try { - fMonarch = Monarch2::OpenForReading(filenames[0].native()); + fMonarch = Monarch2::OpenForReading(filenames[0].first.native()); } catch (M2Exception& e) { @@ -130,6 +130,7 @@ namespace Katydid return Nymph::KTDataPtr(); } CopyHeaderInformation(fMonarch->GetHeader()); + fHeader.SetMetadataFilename(filenames[0].second.native()) KTDEBUG(eggreadlog, "Parsed header:\n" << fHeader); diff --git a/Source/Time/KTEgg3Reader.cc b/Source/Time/KTEgg3Reader.cc index 08669309a..59080316c 100644 --- a/Source/Time/KTEgg3Reader.cc +++ b/Source/Time/KTEgg3Reader.cc @@ -7,6 +7,7 @@ #include "KTEgg3Reader.hh" +#include "KTArbitraryMetadata.hh" #include "KTEggHeader.hh" #include "KTEggProcessor.hh" #include "KTLogger.hh" @@ -20,6 +21,8 @@ #include "M3DataInterface.hh" #include "M3Exception.hh" +#include "param.hh" +#include "param_codec.hh" #include "scarab_version.hh" using namespace monarch3; @@ -40,6 +43,7 @@ namespace Katydid fStride(0), fStartTime(0.), fStartRecord(0), + fRequireMetadata(false), //fHatchNextSlicePtr(NULL), fFilenames(), fCurrentFileIt(), @@ -50,12 +54,12 @@ namespace Katydid fHeader(fHeaderPtr->Of< KTEggHeader >()), fMasterSliceHeader(), fReadState(), - fGetTimeInRun(&KTEgg3Reader::GetTimeInRunFromMonarch), - fT0Offset(0), - fAcqTimeInRun(0), fSampleRateUnitsInHz(1.e6), fRecordSize(0), fBinWidth(0.), + fGetTimeInRun(&KTEgg3Reader::GetTimeInRunFromMonarch), + fT0Offset(0), + fAcqTimeInRun(0), fSliceNumber(0), fRecordsProcessed(0) { @@ -80,6 +84,7 @@ namespace Katydid SetStride(eggProc.GetStride()); SetStartTime(eggProc.GetStartTime()); SetStartRecord(eggProc.GetStartRecord()); + SetRequireMetadata(eggProc.GetRequireMetadata()); return true; } @@ -97,10 +102,10 @@ namespace Katydid fCurrentFileIt = fFilenames.begin(); // open the file - KTINFO(eggreadlog, "Opening egg file <" << fFilenames[0] << ">"); + KTINFO(eggreadlog, "Opening egg file <" << fFilenames[0].first << ">"); try { - fMonarch = Monarch3::OpenForReading(fFilenames[0].native()); + fMonarch = Monarch3::OpenForReading(fFilenames[0].first.native()); } catch (M3Exception& e) { @@ -151,6 +156,15 @@ namespace Katydid fM3StreamHeader = &(fMonarch->GetHeader()->GetStreamHeaders()[streamNum]); CopyHeader(fMonarch->GetHeader()); + fHeader.SetMetadataFilename(fFilenames[0].second.native()); + AddMetadata(); + if (fRequireMetadata && ! MetadataIsPresent()) + { + KTERROR(eggreadlog, "Metadata is required but not present"); + delete fMonarch; + fMonarch = nullptr; + return Nymph::KTDataPtr(); + } KTDEBUG(eggreadlog, "Parsed header:\n" << fHeader); @@ -562,10 +576,10 @@ namespace Katydid } // open the next file - KTINFO(eggreadlog, "Opening next egg file <" << *fCurrentFileIt << ">"); + KTINFO(eggreadlog, "Opening next egg file <" << fCurrentFileIt->first << ">"); try { - fMonarch = Monarch3::OpenForReading(fCurrentFileIt->native()); + fMonarch = Monarch3::OpenForReading(fCurrentFileIt->first.native()); } catch (M3Exception& e) { @@ -687,6 +701,38 @@ namespace Katydid return; } + void KTEgg3Reader::AddMetadata() + { + if (fHeader.GetMetadataFilename().empty()) + { + fHeader.Of< KTArbitraryMetadata >().SetMetadata(nullptr); + return; + } + + scarab::param_translator translator; + scarab::param* metadata = translator.read_file(fHeader.GetMetadataFilename()); + if (metadata == nullptr) + { + KTWARN(eggreadlog, "Metadata file was not present or could not be converted to a param object"); + } +#ifndef NDEBUG + if (metadata != nullptr) + { + KTDEBUG(eggreadlog, "Adding metadata from <" << fHeader.GetMetadataFilename() << ">"); + KTDEBUG(eggreadlog, *metadata); + } +#endif + fHeader.Of< KTArbitraryMetadata >().SetMetadata(metadata); + + return; + } + + bool KTEgg3Reader::MetadataIsPresent() const + { + if (! fHeader.Has< KTArbitraryMetadata >() ) return false; + return fHeader.Of< KTArbitraryMetadata >().GetMetadata() != nullptr; + } + uint32_t ConvertMonarch3DataFormat( uint32_t m3DataFormat ) { diff --git a/Source/Time/KTEgg3Reader.hh b/Source/Time/KTEgg3Reader.hh index 89ef1a18f..d0183403d 100644 --- a/Source/Time/KTEgg3Reader.hh +++ b/Source/Time/KTEgg3Reader.hh @@ -68,23 +68,11 @@ namespace Katydid virtual ~KTEgg3Reader(); public: - unsigned GetSliceSize() const; - void SetSliceSize(unsigned size); - - unsigned GetStride() const; - void SetStride(unsigned stride); - - double GetStartTime() const; - void SetStartTime(double time); - - unsigned GetStartRecord() const; - void SetStartRecord(unsigned rec); - - protected: - unsigned fSliceSize; - unsigned fStride; - double fStartTime; - unsigned fStartRecord; + MEMBERVARIABLE(unsigned, SliceSize); + MEMBERVARIABLE(unsigned, Stride); + MEMBERVARIABLE(double, StartTime); + MEMBERVARIABLE(unsigned, StartRecord); + MEMBERVARIABLE(bool, RequireMetadata); public: bool Configure(const KTEggProcessor& eggProc); @@ -102,6 +90,11 @@ namespace Katydid /// Copy header information from the M3Header object void CopyHeader(const monarch3::M3Header* monarchHeader); + /// Transfer metadata from the metadata file listed in the header to a new KTArbitraryMetadata object + void AddMetadata(); + /// Returns true if (1) a KTArbitraryMetadata is attached to fHeader, and if the metadata param object is non-nullptr + bool MetadataIsPresent() const; + bool LoadNextFile(); //Nymph::KTDataPtr (KTEgg3Reader::*fHatchNextSlicePtr)(); @@ -123,14 +116,14 @@ namespace Katydid MonarchReadState fReadState; public: - double GetSampleRateUnitsInHz() const; + MEMBERVARIABLE_NOSET(double, SampleRateUnitsInHz); + MEMBERVARIABLE_NOSET(unsigned, RecordSize); + MEMBERVARIABLE_NOSET(double, BinWidth); + public: double GetFullVoltageScale() const; unsigned GetNADCLevels() const; - unsigned GetRecordSize() const; - double GetBinWidth() const; - /// Returns the time since the run started in seconds double GetTimeInRun() const; /// Same as GetTimeInRun @@ -154,11 +147,6 @@ namespace Katydid mutable monarch3::TimeType fT0Offset; /// Time of the first record mutable double fAcqTimeInRun; /// Time-in-run of the current acquisition - double fSampleRateUnitsInHz; - - unsigned fRecordSize; - double fBinWidth; - uint64_t fSliceNumber; uint64_t fRecordsProcessed; @@ -168,65 +156,6 @@ namespace Katydid uint32_t ConvertMonarch3DataFormat( uint32_t m3DataFormat ); - - inline unsigned KTEgg3Reader::GetSliceSize() const - { - return fSliceSize; - } - - inline void KTEgg3Reader::SetSliceSize(unsigned size) - { - fSliceSize = size; - return; - } - - inline unsigned KTEgg3Reader::GetStride() const - { - return fStride; - } - - inline void KTEgg3Reader::SetStride(unsigned stride) - { - fStride = stride; - return; - } - - inline double KTEgg3Reader::GetStartTime() const - { - return fStartTime; - } - - inline void KTEgg3Reader::SetStartTime(double time) - { - fStartTime = time; - return; - } - - inline unsigned KTEgg3Reader::GetStartRecord() const - { - return fStartRecord; - } - - inline void KTEgg3Reader::SetStartRecord(unsigned rec) - { - fStartRecord = rec; - return; - } - - inline double KTEgg3Reader::GetSampleRateUnitsInHz() const - { - return fSampleRateUnitsInHz; - } - - inline unsigned KTEgg3Reader::GetRecordSize() const - { - return fRecordSize; - } - inline double KTEgg3Reader::GetBinWidth() const - { - return fBinWidth; - } - inline double KTEgg3Reader::GetTimeInRun() const { return (this->*fGetTimeInRun)(); diff --git a/Source/Time/KTEggProcessor.cc b/Source/Time/KTEggProcessor.cc index 53bc701c0..63a3d2ec0 100644 --- a/Source/Time/KTEggProcessor.cc +++ b/Source/Time/KTEggProcessor.cc @@ -25,6 +25,7 @@ namespace Katydid { static Nymph::KTCommandLineOption< int > sNsCLO("Egg Processor", "Number of slices to process", "n-slices", 'n'); static Nymph::KTCommandLineOption< string > sFilenameCLO("Egg Processor", "Egg filename to open", "egg-file", 'e'); + static Nymph::KTCommandLineOption< string > sMetadataCLO("Egg Processor", "Metadata filename to open", "metadata-file", 'm'); static Nymph::KTCommandLineOption< bool > sOldReaderCLO("Egg Processor", "Use the egg1 (2011) reader", "use-egg1-reader", 'z'); KTLOGGER(egglog, "KTEggProcessor"); @@ -37,6 +38,7 @@ namespace Katydid fProgressReportInterval(1), fFilenames(), fEggReaderType("none"), + fRequireMetadata(false), fSliceSize(1024), fStride(1024), fStartTime(0.), @@ -82,21 +84,41 @@ namespace Katydid { KTDEBUG(egglog, "Adding single file to egg processor"); fFilenames.clear(); - fFilenames.push_back( std::move(scarab::expand_path(node->get_value( "filename" ))) ); - KTINFO(egglog, "Added file to egg processor: <" << fFilenames.back() << ">"); + scarab::path metadataFilename; + if (node->has("metadata")) + { + metadataFilename = scarab::expand_path(node->get_value( "metadata" )); + KTINFO(egglog, "Added metadata file to egg processor: <" << metadataFilename << ">" ); + } + fFilenames.push_back( std::make_pair(scarab::expand_path(node->get_value( "filename" )), metadataFilename) ); + KTINFO(egglog, "Added file to egg processor:\n" << + "\tegg: <" << fFilenames.back().first << ">\n" << + "\tmetadata: <" << fFilenames.back().second << ">"); } else if (node->has("filenames")) { KTDEBUG(egglog, "Adding multiple files to egg processor"); fFilenames.clear(); - const scarab::param_array* t_filenames = node->array_at("filenames"); - for(scarab::param_array::const_iterator t_file_it = t_filenames->begin(); t_file_it != t_filenames->end(); ++t_file_it) + const scarab::param_array* tConfigFilenames = node->array_at("filenames"); + const scarab::param_array* tConfigMetadatas = node->array_at("metadata"); + if( tConfigMetadatas != nullptr && tConfigMetadatas->size() != tConfigFilenames->size() ) { - fFilenames.push_back( std::move(scarab::expand_path((*t_file_it)->as_value().as_string())) ); - KTINFO(egglog, "Added file to egg processor: <" << fFilenames.back() << ">"); + KTERROR(egglog, "Number of egg files (" << tConfigFilenames->size() << ") and metadata files (" << tConfigMetadatas->size() << ") were not the same"); + return false; + } + scarab::path metadataFilename; + for (unsigned iFile = 0; iFile < tConfigFilenames->size(); ++iFile) + { + if (tConfigMetadatas != nullptr ) metadataFilename = scarab::expand_path((*tConfigMetadatas)[iFile].as_value().as_string()); + fFilenames.push_back( std::make_pair(scarab::expand_path((*tConfigFilenames)[iFile].as_value().as_string()), metadataFilename) ); + KTINFO(egglog, "Added file to egg processor:\n" << + "\tegg: <" << fFilenames.back().first << ">\n" << + "\tmetadata: <" << fFilenames.back().second << ">"); } } + fRequireMetadata = node->get_value< bool >("require-metadata", fRequireMetadata); + // specify the length of the time series fSliceSize = node->get_value< unsigned >("slice-size", fSliceSize); // specify the stride (leave unset to make stride == slice size) @@ -125,10 +147,21 @@ namespace Katydid SetNSlices(fCLHandler->GetCommandLineValue< int >("n-slices", fNSlices)); if (fCLHandler->IsCommandLineOptSet("egg-file")) { - KTDEBUG(egglog, "Adding single file to egg processor from the CL"); + KTDEBUG(egglog, "Specifying single egg file to egg processor from the CL"); fFilenames.clear(); - fFilenames.push_back( std::move(scarab::expand_path(fCLHandler->GetCommandLineValue< string >("egg-file")))); - KTINFO(egglog, "Added file to egg processor: <" << fFilenames.back() << ">"); + fFilenames.push_back( std::make_pair(scarab::expand_path(fCLHandler->GetCommandLineValue< string >("egg-file")), scarab::path()) ); + KTINFO(egglog, "Added egg file to egg processor: <" << fFilenames.back().first << ">"); + } + if (fCLHandler->IsCommandLineOptSet("metadata-file")) + { + if (fFilenames.size() != 1) + { + KTERROR(egglog, "Can only specify metadata file if there's already a single egg file specified" ); + return false; + } + KTDEBUG(egglog, "Specifying single metadata file to egg processor from the CL"); + fFilenames.back().second = scarab::expand_path(fCLHandler->GetCommandLineValue< string >("metadata-file")); + KTINFO(egglog, "Added metadata file to egg processor: <" << fFilenames.back().second << ">"); } return true; diff --git a/Source/Time/KTEggProcessor.hh b/Source/Time/KTEggProcessor.hh index bae7275e0..2af98b7a0 100644 --- a/Source/Time/KTEggProcessor.hh +++ b/Source/Time/KTEggProcessor.hh @@ -36,14 +36,17 @@ namespace Katydid Configuration name: "egg-processor" Available configuration options: - - "number-of-slices": unsigned -- Number of slices to process + - "number-of-slices": unsigned -- Number of slices to process (set to 0 to process all slices in the file) - "progress-report-interval": unsigned -- Interval (# of slices) between reporting progress (mainly relevant for RELEASE builds); turn off by setting to 0 - "filename": string -- Egg filename to use (will take priority over \"filenames\") - "filenames": array of strings -- Egg filenames to use (\"filename\" will take priority over this) + - "metadata": string or array of strings -- Metadata filenames to use (if present, number of files must match the number of egg files specified) + - "require-metadata": bool -- Flag to determine whether metadata is required or not (default) - "egg-reader": string -- Egg reader to use. - Options: "egg2" [default], "egg1", "rsamat" - - "egg2" [default] - Uses the monarch2 library to read Egg files + Options: "egg3", "egg2", "egg1", "rsamat" + - "egg3" - Uses the monarch3 library to read Egg files + - "egg2" - Uses the monarch2 library to read Egg files - "egg1" - uses the old style Egg reader, which opens and reads the contents of the Egg file directly - "rsamat" - reads matlab (mat) files generated by the Tektronix RSA, @@ -62,6 +65,7 @@ namespace Katydid Command-line options defined - -n (n-slices): Number of slices to process - -e (egg-file): Egg filename to use + - -m (metadata-file): Metadata filename to use - -z (--use-2011-egg-reader): Use the 2011 egg reader Signals: @@ -94,6 +98,7 @@ namespace Katydid MEMBERVARIABLEREF(KTEggReader::path_vec, Filenames); MEMBERVARIABLEREF(std::string, EggReaderType); + MEMBERVARIABLE(bool, RequireMetadata); MEMBERVARIABLE(unsigned, SliceSize); MEMBERVARIABLE(unsigned, Stride); diff --git a/Source/Time/KTEggReader.hh b/Source/Time/KTEggReader.hh index 0e83c0d94..df656574d 100644 --- a/Source/Time/KTEggReader.hh +++ b/Source/Time/KTEggReader.hh @@ -23,7 +23,8 @@ namespace Katydid class KTEggReader { public: - typedef std::vector< scarab::path > path_vec; + typedef std::pair< scarab::path, scarab::path > path_pair; + typedef std::vector< path_pair > path_vec; public: KTEggReader(); @@ -32,7 +33,7 @@ namespace Katydid public: virtual bool Configure(const KTEggProcessor& eggProc) = 0; - Nymph::KTDataPtr BreakAnEgg(const std::string& filename); + Nymph::KTDataPtr BreakAnEgg(const std::string& eggFilename, const std::string& metadataFilename = ""); virtual Nymph::KTDataPtr BreakEgg(const path_vec&) = 0; virtual Nymph::KTDataPtr HatchNextSlice() = 0; virtual bool CloseEgg() = 0; @@ -43,10 +44,10 @@ namespace Katydid }; - inline Nymph::KTDataPtr KTEggReader::BreakAnEgg(const std::string& filename) + inline Nymph::KTDataPtr KTEggReader::BreakAnEgg(const std::string& eggFilename, const std::string& metadataFilename) { path_vec filenameVec; - filenameVec.emplace_back(filename); + filenameVec.emplace_back(std::make_pair(eggFilename, metadataFilename)); return BreakEgg(filenameVec); } diff --git a/Source/Time/KTRSAMatReader.cc b/Source/Time/KTRSAMatReader.cc index 172748cfb..db30d3760 100644 --- a/Source/Time/KTRSAMatReader.cc +++ b/Source/Time/KTRSAMatReader.cc @@ -96,11 +96,11 @@ namespace Katydid { KTWARN(eggreadlog, "RSAMAT reader is only setup to handle a single file; multiple files have been specified and all but the first one will be skipped"); } - KTINFO(eggreadlog, "Opening mat file <" << filenames[0] << ">"); - fMatFilePtr = Mat_Open(filenames[0].c_str(), MAT_ACC_RDONLY); + KTINFO(eggreadlog, "Opening mat file <" << filenames[0].first << ">"); + fMatFilePtr = Mat_Open(filenames[0].first.c_str(), MAT_ACC_RDONLY); if (fMatFilePtr == NULL) { - KTERROR(eggreadlog, "Unable to open mat file: " << filenames[0]); + KTERROR(eggreadlog, "Unable to open mat file: " << filenames[0].first); return Nymph::KTDataPtr(); } @@ -268,7 +268,8 @@ namespace Katydid //printf("Sampling Frequency: %s\n", curr_node->value()); // Write configuration from XML into fHeader variable - fHeader.SetFilename(filenames[0].native()); + fHeader.SetFilename(filenames[0].first.native()); + fHeader.SetMetadataFilename(filenames[0].second.native()); fHeader.SetNChannels(1); fHeader.SetChannelHeader(new KTChannelHeader()); curr_node = data_node->first_node("NumberSamples");