From 4d602d01986010500c0d9123c85a59d813292410 Mon Sep 17 00:00:00 2001 From: Penny Slocum Date: Wed, 3 Sep 2025 14:33:18 -0400 Subject: [PATCH 1/3] Add signal if metadata is present. Signal matches KTTerminalWriter slot for terminal output. --- Source/Time/KTEggProcessor.cc | 8 ++++++++ Source/Time/KTEggProcessor.hh | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/Source/Time/KTEggProcessor.cc b/Source/Time/KTEggProcessor.cc index 63a3d2ec0..fe9cc9586 100644 --- a/Source/Time/KTEggProcessor.cc +++ b/Source/Time/KTEggProcessor.cc @@ -39,6 +39,7 @@ namespace Katydid fFilenames(), fEggReaderType("none"), fRequireMetadata(false), + fHaveMetadata(false), fSliceSize(1024), fStride(1024), fStartTime(0.), @@ -47,6 +48,7 @@ namespace Katydid fNormalizeVoltages(true), fHeaderSignal("header", this), fRawDataSignal("raw-ts", this), + fMetadataSignal("metadata", this), fDataSignal("ts", this), fEggDoneSignal("egg-done", this), fSummarySignal("summary", this) @@ -159,6 +161,7 @@ namespace Katydid KTERROR(egglog, "Can only specify metadata file if there's already a single egg file specified" ); return false; } + fHaveMetadata = true; 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 << ">"); @@ -205,6 +208,11 @@ namespace Katydid } fHeaderSignal(headerPtr); + if ( fHaveMetadata ) + { + fMetadataSignal(headerPtr); + } + KTINFO(egglog, "The egg file has been opened successfully and the header was parsed and processed;"); KTPROG(egglog, "Proceeding with slice processing"); diff --git a/Source/Time/KTEggProcessor.hh b/Source/Time/KTEggProcessor.hh index 2af98b7a0..a316a8596 100644 --- a/Source/Time/KTEggProcessor.hh +++ b/Source/Time/KTEggProcessor.hh @@ -74,6 +74,7 @@ namespace Katydid produced; guarantees KTRawTimeSeriesData - "ts": void (Nymph::KTDataPtr) -- emitted when the new calibrated time series is produced; Guarantees KTTimeSeriesData + - "metadata": void (Nymph::KTDataPtr) -- emitted when the file header is parsed. - "egg-done": void () -- emitted when a file is finished. - "summary": void (const KTProcSummary*) -- emitted when a file is finished (after "egg-done") @@ -99,6 +100,8 @@ namespace Katydid MEMBERVARIABLEREF(KTEggReader::path_vec, Filenames); MEMBERVARIABLEREF(std::string, EggReaderType); MEMBERVARIABLE(bool, RequireMetadata); + MEMBERVARIABLE(bool, HaveMetadata); + MEMBERVARIABLE(unsigned, SliceSize); MEMBERVARIABLE(unsigned, Stride); @@ -131,6 +134,7 @@ namespace Katydid Nymph::KTSignalData fHeaderSignal; Nymph::KTSignalData fRawDataSignal; Nymph::KTSignalData fDataSignal; + Nymph::KTSignalData fMetadataSignal; Nymph::KTSignalOneArg< void > fEggDoneSignal; Nymph::KTSignalOneArg< const KTProcSummary* > fSummarySignal; From cb4fcab5c322978b0216efe3fab6c6698493ac68 Mon Sep 17 00:00:00 2001 From: Penny Slocum Date: Thu, 4 Sep 2025 14:31:17 -0400 Subject: [PATCH 2/3] Temporary commit to write arbitrary metadata structure to json file. For flexibility, the metadata structure will likely need to be versioned and saved elsewhere (TBD). --- Source/IO/JSONWriter/KTJSONTypeWriterTime.cc | 103 +++++++++++++++++++ Source/IO/JSONWriter/KTJSONTypeWriterTime.hh | 2 + 2 files changed, 105 insertions(+) diff --git a/Source/IO/JSONWriter/KTJSONTypeWriterTime.cc b/Source/IO/JSONWriter/KTJSONTypeWriterTime.cc index f95786a6f..c4ea83ce8 100644 --- a/Source/IO/JSONWriter/KTJSONTypeWriterTime.cc +++ b/Source/IO/JSONWriter/KTJSONTypeWriterTime.cc @@ -5,9 +5,11 @@ * Author: nsoblath */ +#include "KTArbitraryMetadata.hh" #include "KTEggHeader.hh" #include "KTJSONTypeWriterTime.hh" #include "KTTIFactory.hh" + //#include "KTLogger.hh" using std::string; @@ -32,6 +34,107 @@ namespace Katydid void KTJSONTypeWriterTime::RegisterSlots() { fWriter->RegisterSlot("header", this, &KTJSONTypeWriterTime::WriteEggHeader); + fWriter->RegisterSlot("metadata", this, &KTJSONTypeWriterTime::WriteArbitraryMetadata); + return; + } + + + void KTJSONTypeWriterTime::WriteArbitraryMetadata(Nymph::KTDataPtr data) + { + + using rapidjson::SizeType; + + if (! fWriter->OpenAndVerifyFile()) return; + + if (! data) return; + + scarab::param* metadata = data->Of< KTArbitraryMetadata >().GetMetadata(); + + KTJSONWriter::JSONMaker* jsonMaker = fWriter->GetJSONMaker(); + + jsonMaker->String("run-id"); + jsonMaker->String(metadata->as_node()["run-id"]().as_string().c_str()); + + jsonMaker->String("run-parameters"); + jsonMaker->StartObject(); + jsonMaker->String("run-type"); + jsonMaker->String(metadata->as_node()["run-parameters"]["run-type"]().as_string().c_str()); + jsonMaker->String("simulation-type"); + jsonMaker->String(metadata->as_node()["run-parameters"]["simulation-type"]().as_string().c_str()); + jsonMaker->String("simulation-subtype"); + jsonMaker->String(metadata->as_node()["run-parameters"]["simulation-subtype"]().as_string().c_str()); + jsonMaker->String("user-defined-tag"); + jsonMaker->String(metadata->as_node()["run-parameters"]["user-defined-tag"]().as_string().c_str()); + jsonMaker->String("sampling-freq-mega-hz"); + jsonMaker->String(metadata->as_node()["run-parameters"]["sampling-freq-mega-hz"]().as_string().c_str()); + jsonMaker->String("configured-e-min"); + jsonMaker->String(metadata->as_node()["run-parameters"]["configured-e-min"]().as_string().c_str()); + jsonMaker->String("configured-pitch-min"); + jsonMaker->String(metadata->as_node()["run-parameters"]["configured-pitch-min"]().as_string().c_str()); + jsonMaker->String("configured-x-min"); + jsonMaker->String(metadata->as_node()["run-parameters"]["configured-x-min"]().as_string().c_str()); + jsonMaker->String("configured-y-min"); + jsonMaker->String(metadata->as_node()["run-parameters"]["configured-y-min"]().as_string().c_str()); + jsonMaker->String("configured-z-min"); + jsonMaker->String(metadata->as_node()["run-parameters"]["configured-z-min"]().as_string().c_str()); + jsonMaker->EndObject(); + + jsonMaker->String("nevents"); + jsonMaker->String(metadata->as_node()["nevents"]().as_string().c_str()); + + for (int iEvent = 0; iEvent < metadata->as_node()["nevents"]().as_int(); iEvent++) + { + jsonMaker->String(std::to_string(iEvent).c_str()); + jsonMaker->StartObject(); + jsonMaker->String("event-tag"); + jsonMaker->String(metadata->as_node()[std::to_string(iEvent)]["event-tag"]().as_string().c_str()); + jsonMaker->String("kassiopeia-seed"); + jsonMaker->String(metadata->as_node()[std::to_string(iEvent)]["kassiopeia-seed"]().as_string().c_str()); + jsonMaker->String("track-length-seed"); + jsonMaker->String(metadata->as_node()[std::to_string(iEvent)]["track-length-seed"]().as_string().c_str()); + jsonMaker->String("track-delay-seed"); + jsonMaker->String(metadata->as_node()[std::to_string(iEvent)]["track-delay-seed"]().as_string().c_str()); + jsonMaker->String("ntracks"); + jsonMaker->String(metadata->as_node()[std::to_string(iEvent)]["ntracks"]().as_string().c_str()); + for (int iTrack = 0; iTrack < metadata->as_node()[std::to_string(iEvent)]["ntracks"]().as_int(); iTrack++) + { + jsonMaker->String(std::to_string(iTrack).c_str()); + jsonMaker->StartObject(); + jsonMaker->String("start-time"); + jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["start-time"]().as_double()); + jsonMaker->String("end-time"); + jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["end-time"]().as_double()); + jsonMaker->String("energy-ev"); + jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["energy-ev"]().as_double()); + jsonMaker->String("start-radius"); + jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["start-radius"]().as_double()); + jsonMaker->String("start-radial-phase"); + jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["start-radial-phase"]().as_double()); + jsonMaker->String("output-avg-frequency"); + jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["output-avg-frequency"]().as_double()); + jsonMaker->String("output-track-start-frequency"); + jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["output-track-start-frequency"]().as_double()); + jsonMaker->String("output-inst-start-frequency"); + jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["output-inst-start-frequency"]().as_double()); + jsonMaker->String("pitch-angle"); + jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["pitch-angle"]().as_double()); + jsonMaker->String("slope"); + jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["slope"]().as_double()); + jsonMaker->String("avg-axial-frequency"); + jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["avg-axial-frequency"]().as_double()); + + jsonMaker->EndObject(); + + + } + + jsonMaker->EndObject(); + } + + + +// fWriter->CloseFile(); + return; } diff --git a/Source/IO/JSONWriter/KTJSONTypeWriterTime.hh b/Source/IO/JSONWriter/KTJSONTypeWriterTime.hh index 6c0252a2a..fd5cb640f 100644 --- a/Source/IO/JSONWriter/KTJSONTypeWriterTime.hh +++ b/Source/IO/JSONWriter/KTJSONTypeWriterTime.hh @@ -27,6 +27,8 @@ namespace Katydid public: void WriteEggHeader(Nymph::KTDataPtr headerPtr); + void WriteArbitraryMetadata(Nymph::KTDataPtr data); + }; } /* namespace Katydid */ From 998eadab0e7102f4de5615f196f7e0fba231f1a7 Mon Sep 17 00:00:00 2001 From: Penny Slocum Date: Wed, 17 Sep 2025 16:23:51 -0400 Subject: [PATCH 3/3] Temporary commit for testing: Use scarab::param_output_json to parse and write arbitrary metadata file (with arbitrary structure) specified on the command line. --- Source/IO/JSONWriter/KTJSONTypeWriterTime.cc | 88 ++------------------ 1 file changed, 5 insertions(+), 83 deletions(-) diff --git a/Source/IO/JSONWriter/KTJSONTypeWriterTime.cc b/Source/IO/JSONWriter/KTJSONTypeWriterTime.cc index c4ea83ce8..2e3b47232 100644 --- a/Source/IO/JSONWriter/KTJSONTypeWriterTime.cc +++ b/Source/IO/JSONWriter/KTJSONTypeWriterTime.cc @@ -11,6 +11,9 @@ #include "KTTIFactory.hh" //#include "KTLogger.hh" +#include "param.hh" +#include "param_json.hh" + using std::string; @@ -50,90 +53,9 @@ namespace Katydid scarab::param* metadata = data->Of< KTArbitraryMetadata >().GetMetadata(); - KTJSONWriter::JSONMaker* jsonMaker = fWriter->GetJSONMaker(); - - jsonMaker->String("run-id"); - jsonMaker->String(metadata->as_node()["run-id"]().as_string().c_str()); - - jsonMaker->String("run-parameters"); - jsonMaker->StartObject(); - jsonMaker->String("run-type"); - jsonMaker->String(metadata->as_node()["run-parameters"]["run-type"]().as_string().c_str()); - jsonMaker->String("simulation-type"); - jsonMaker->String(metadata->as_node()["run-parameters"]["simulation-type"]().as_string().c_str()); - jsonMaker->String("simulation-subtype"); - jsonMaker->String(metadata->as_node()["run-parameters"]["simulation-subtype"]().as_string().c_str()); - jsonMaker->String("user-defined-tag"); - jsonMaker->String(metadata->as_node()["run-parameters"]["user-defined-tag"]().as_string().c_str()); - jsonMaker->String("sampling-freq-mega-hz"); - jsonMaker->String(metadata->as_node()["run-parameters"]["sampling-freq-mega-hz"]().as_string().c_str()); - jsonMaker->String("configured-e-min"); - jsonMaker->String(metadata->as_node()["run-parameters"]["configured-e-min"]().as_string().c_str()); - jsonMaker->String("configured-pitch-min"); - jsonMaker->String(metadata->as_node()["run-parameters"]["configured-pitch-min"]().as_string().c_str()); - jsonMaker->String("configured-x-min"); - jsonMaker->String(metadata->as_node()["run-parameters"]["configured-x-min"]().as_string().c_str()); - jsonMaker->String("configured-y-min"); - jsonMaker->String(metadata->as_node()["run-parameters"]["configured-y-min"]().as_string().c_str()); - jsonMaker->String("configured-z-min"); - jsonMaker->String(metadata->as_node()["run-parameters"]["configured-z-min"]().as_string().c_str()); - jsonMaker->EndObject(); + scarab::param_output_json tOutput; - jsonMaker->String("nevents"); - jsonMaker->String(metadata->as_node()["nevents"]().as_string().c_str()); - - for (int iEvent = 0; iEvent < metadata->as_node()["nevents"]().as_int(); iEvent++) - { - jsonMaker->String(std::to_string(iEvent).c_str()); - jsonMaker->StartObject(); - jsonMaker->String("event-tag"); - jsonMaker->String(metadata->as_node()[std::to_string(iEvent)]["event-tag"]().as_string().c_str()); - jsonMaker->String("kassiopeia-seed"); - jsonMaker->String(metadata->as_node()[std::to_string(iEvent)]["kassiopeia-seed"]().as_string().c_str()); - jsonMaker->String("track-length-seed"); - jsonMaker->String(metadata->as_node()[std::to_string(iEvent)]["track-length-seed"]().as_string().c_str()); - jsonMaker->String("track-delay-seed"); - jsonMaker->String(metadata->as_node()[std::to_string(iEvent)]["track-delay-seed"]().as_string().c_str()); - jsonMaker->String("ntracks"); - jsonMaker->String(metadata->as_node()[std::to_string(iEvent)]["ntracks"]().as_string().c_str()); - for (int iTrack = 0; iTrack < metadata->as_node()[std::to_string(iEvent)]["ntracks"]().as_int(); iTrack++) - { - jsonMaker->String(std::to_string(iTrack).c_str()); - jsonMaker->StartObject(); - jsonMaker->String("start-time"); - jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["start-time"]().as_double()); - jsonMaker->String("end-time"); - jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["end-time"]().as_double()); - jsonMaker->String("energy-ev"); - jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["energy-ev"]().as_double()); - jsonMaker->String("start-radius"); - jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["start-radius"]().as_double()); - jsonMaker->String("start-radial-phase"); - jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["start-radial-phase"]().as_double()); - jsonMaker->String("output-avg-frequency"); - jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["output-avg-frequency"]().as_double()); - jsonMaker->String("output-track-start-frequency"); - jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["output-track-start-frequency"]().as_double()); - jsonMaker->String("output-inst-start-frequency"); - jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["output-inst-start-frequency"]().as_double()); - jsonMaker->String("pitch-angle"); - jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["pitch-angle"]().as_double()); - jsonMaker->String("slope"); - jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["slope"]().as_double()); - jsonMaker->String("avg-axial-frequency"); - jsonMaker->Double(metadata->as_node()[std::to_string(iEvent)][std::to_string(iTrack)]["avg-axial-frequency"]().as_double()); - - jsonMaker->EndObject(); - - - } - - jsonMaker->EndObject(); - } - - - -// fWriter->CloseFile(); + bool t_did_write_file = tOutput.write_file( *metadata, fWriter->GetFilename() ); return; }