From 06a85ece9639c1fa1198920a674ce0c3fb4fe840 Mon Sep 17 00:00:00 2001 From: 2xB <2xB@users.noreply.github.com> Date: Wed, 11 Dec 2024 03:07:23 +0100 Subject: [PATCH] KSWriteASCII: Fix headers, add type prefixes before lines Before, the single header row contained a list of all outputs, mixing e.g. track and step outputs. With this commit, there are multiple header rows, splitting the header up into step, track etc. output. To use the header meaningfully, the further lines are also prepended by "track", "step" etc. indicating their type. Also, since outputs have been observed to change order at random (which still has to be understood and if possible avoided), this commit uses fActive*Component to list the actually used components in their correct order. --- Kassiopeia/Writers/Include/KSWriteASCII.h | 24 +- Kassiopeia/Writers/Source/KSWriteASCII.cxx | 352 +++++++++------------ 2 files changed, 168 insertions(+), 208 deletions(-) diff --git a/Kassiopeia/Writers/Include/KSWriteASCII.h b/Kassiopeia/Writers/Include/KSWriteASCII.h index b47340a3..40a85f3b 100644 --- a/Kassiopeia/Writers/Include/KSWriteASCII.h +++ b/Kassiopeia/Writers/Include/KSWriteASCII.h @@ -16,18 +16,18 @@ class KSWriteASCII : public KSComponentTemplate class Data { public: - Data(KSComponent* aComponent, KSWriteASCII* aWriter); + Data(KSComponent* aComponent, int aPrecision); ~Data(); + void Initialize(KSComponent* aComponent, int aPrecision); void Start(const unsigned int& anIndex); std::string ValuesAsString(); - void MakeTitle(KSComponent* aComponent, int aTrack); + std::string Label(); private: std::string fLabel; std::string fType; - KSWriteASCII* fWriter; unsigned int fIndex; unsigned int fLength; @@ -67,10 +67,11 @@ class KSWriteASCII : public KSComponentTemplate katrin::KTextFile* TextFile(); void Write(std::string str); + void Write(char c); int Precision() const; protected: - katrin::KTextFile* MakeOutputFile(int anIndex) const; + void MakeOutputFile(int anIndex); private: std::string fBase; @@ -163,19 +164,32 @@ inline void KSWriteASCII::SetPrecision(const unsigned int& aValue) inline katrin::KTextFile* KSWriteASCII::TextFile() { + if (!fTextFile) + MakeOutputFile(fTrackIndex); + return fTextFile; } inline void KSWriteASCII::Write(std::string str) { for (char& it : str) - fTextFile->File()->put(it); + TextFile()->File()->put(it); +} + +inline void KSWriteASCII::Write(char c) +{ + TextFile()->File()->put(c); } inline int KSWriteASCII::Precision() const { return fPrecision; } + +inline std::string KSWriteASCII::Data::Label() +{ + return fLabel; +} } // namespace Kassiopeia diff --git a/Kassiopeia/Writers/Source/KSWriteASCII.cxx b/Kassiopeia/Writers/Source/KSWriteASCII.cxx index f08dd4e7..2cc615f9 100644 --- a/Kassiopeia/Writers/Source/KSWriteASCII.cxx +++ b/Kassiopeia/Writers/Source/KSWriteASCII.cxx @@ -86,15 +86,14 @@ string KSWriteASCII::Data::OutputObjectASCII::getValue() return s.str(); } -KSWriteASCII::Data::Data(KSComponent* aComponent, KSWriteASCII* aWriter) : +KSWriteASCII::Data::Data(KSComponent* aComponent, int aPrecision) : fLabel(""), fType(""), fIndex(0), fLength(0), fComponents() { - fWriter = aWriter; - MakeTitle(aComponent, 0); + Initialize(aComponent, aPrecision); } KSWriteASCII::Data::~Data() = default; @@ -130,7 +129,7 @@ std::string KSWriteASCII::Data::ValuesAsString() return result; } -void KSWriteASCII::Data::MakeTitle(KSComponent* aComponent, int aTrack) +void KSWriteASCII::Data::Initialize(KSComponent* aComponent, int aPrecision) { wtrmsg_debug("making title for object <" << aComponent->GetName() << ">" << eom); @@ -138,7 +137,7 @@ void KSWriteASCII::Data::MakeTitle(KSComponent* aComponent, int aTrack) if (tComponentGroup != nullptr) { wtrmsg_debug(" object <" << aComponent->GetName() << "> is a group" << eom); for (unsigned int tIndex = 0; tIndex < tComponentGroup->ComponentCount(); tIndex++) - MakeTitle(tComponentGroup->ComponentAt(tIndex), aTrack); + Initialize(tComponentGroup->ComponentAt(tIndex), aPrecision); return; } @@ -146,16 +145,11 @@ void KSWriteASCII::Data::MakeTitle(KSComponent* aComponent, int aTrack) auto* tString = aComponent->As(); if (tString != nullptr) { wtrmsg_debug(" object <" << aComponent->GetName() << "> is a string" << eom); - string str = (aComponent->GetName() + '\t'); + fLabel += (aComponent->GetName() + '\t'); - for (char& it : str) - fWriter->TextFile()->File()->put(it); - - if (aTrack == 0) { - auto* obj = new OutputObjectASCII(aComponent, "string", fWriter->Precision()); - fOutputObjectASCIIs.push_back(obj); - fComponents.push_back(aComponent); - } + auto* obj = new OutputObjectASCII(aComponent, "string", aPrecision); + fOutputObjectASCIIs.push_back(obj); + fComponents.push_back(aComponent); return; } @@ -163,263 +157,201 @@ void KSWriteASCII::Data::MakeTitle(KSComponent* aComponent, int aTrack) auto* tTwoVector = aComponent->As(); if (tTwoVector != nullptr) { wtrmsg_debug(" object <" << aComponent->GetName() << "> is a two_vector" << eom); - string str = (aComponent->GetName() + string("_x") + '\t' + aComponent->GetName() + string("_y") + '\t'); - - for (char& it : str) - fWriter->TextFile()->File()->put(it); + fLabel += (aComponent->GetName() + string("_x") + '\t' + aComponent->GetName() + string("_y") + '\t'); - if (aTrack == 0) { - auto* obj = new OutputObjectASCII(aComponent, "KTwoVector", fWriter->Precision()); - fOutputObjectASCIIs.push_back(obj); - fComponents.push_back(aComponent); - } + auto* obj = new OutputObjectASCII(aComponent, "KTwoVector", aPrecision); + fOutputObjectASCIIs.push_back(obj); + fComponents.push_back(aComponent); + return; } auto* tThreeVector = aComponent->As(); if (tThreeVector != nullptr) { wtrmsg_debug(" object <" << aComponent->GetName() << "> is a three_vector" << eom); - string str = (aComponent->GetName() + string("_x") + '\t' + aComponent->GetName() + string("_y") + '\t' + - aComponent->GetName() + string("_z") + '\t'); + fLabel += (aComponent->GetName() + string("_x") + '\t' + aComponent->GetName() + string("_y") + '\t' + + aComponent->GetName() + string("_z") + '\t'); - for (char& it : str) - fWriter->TextFile()->File()->put(it); - - if (aTrack == 0) { - auto* obj = new OutputObjectASCII(aComponent, "KThreeVector", fWriter->Precision()); - fOutputObjectASCIIs.push_back(obj); - fComponents.push_back(aComponent); - } + auto* obj = new OutputObjectASCII(aComponent, "KThreeVector", aPrecision); + fOutputObjectASCIIs.push_back(obj); + fComponents.push_back(aComponent); + return; } auto* tTwoMatrix = aComponent->As(); if (tTwoMatrix != nullptr) { wtrmsg_debug(" object <" << aComponent->GetName() << "> is a two_matrix" << eom); - string str = (aComponent->GetName() + string("_xx") + '\t' + aComponent->GetName() + string("_xy") + - aComponent->GetName() + string("_yx") + '\t' + aComponent->GetName() + string("_yy")); - - for (char& it : str) - fWriter->TextFile()->File()->put(it); + fLabel += (aComponent->GetName() + string("_xx") + '\t' + aComponent->GetName() + string("_xy") + + aComponent->GetName() + string("_yx") + '\t' + aComponent->GetName() + string("_yy")); - if (aTrack == 0) { - auto* obj = new OutputObjectASCII(aComponent, "KTwoMatrix", fWriter->Precision()); - fOutputObjectASCIIs.push_back(obj); - fComponents.push_back(aComponent); - } + auto* obj = new OutputObjectASCII(aComponent, "KTwoMatrix", aPrecision); + fOutputObjectASCIIs.push_back(obj); + fComponents.push_back(aComponent); + return; } + auto* tThreeMatrix = aComponent->As(); if (tThreeMatrix != nullptr) { wtrmsg_debug(" object <" << aComponent->GetName() << "> is a three_matrix" << eom); - string str = (aComponent->GetName() + string("_xx") + '\t' + aComponent->GetName() + string("_xy") + '\t' + aComponent->GetName() + string("_xz") + '\t' + - aComponent->GetName() + string("_yx") + '\t' + aComponent->GetName() + string("_yy") + '\t' + aComponent->GetName() + string("_yz") + '\t' + - aComponent->GetName() + string("_zx") + '\t' + aComponent->GetName() + string("_zy") + '\t' + aComponent->GetName() + string("_zz") + '\t'); - - for (char& it : str) - fWriter->TextFile()->File()->put(it); - - if (aTrack == 0) { - auto* obj = new OutputObjectASCII(aComponent, "KThreeMatrix", fWriter->Precision()); - fOutputObjectASCIIs.push_back(obj); - fComponents.push_back(aComponent); - } + fLabel += (aComponent->GetName() + string("_xx") + '\t' + aComponent->GetName() + string("_xy") + '\t' + aComponent->GetName() + string("_xz") + '\t' + + aComponent->GetName() + string("_yx") + '\t' + aComponent->GetName() + string("_yy") + '\t' + aComponent->GetName() + string("_yz") + '\t' + + aComponent->GetName() + string("_zx") + '\t' + aComponent->GetName() + string("_zy") + '\t' + aComponent->GetName() + string("_zz") + '\t'); + + auto* obj = new OutputObjectASCII(aComponent, "KThreeMatrix", aPrecision); + fOutputObjectASCIIs.push_back(obj); + fComponents.push_back(aComponent); + return; } auto* tBool = aComponent->As(); if (tBool != nullptr) { wtrmsg_debug(" object <" << aComponent->GetName() << "> is a bool" << eom); - string str = (aComponent->GetName() + '\t'); + fLabel += (aComponent->GetName() + '\t'); - for (char& it : str) - fWriter->TextFile()->File()->put(it); - - if (aTrack == 0) { - auto* obj = new OutputObjectASCII(aComponent, "bool", fWriter->Precision()); - fOutputObjectASCIIs.push_back(obj); - fComponents.push_back(aComponent); - } + auto* obj = new OutputObjectASCII(aComponent, "bool", aPrecision); + fOutputObjectASCIIs.push_back(obj); + fComponents.push_back(aComponent); + return; } auto* tUChar = aComponent->As(); if (tUChar != nullptr) { wtrmsg_debug(" object <" << aComponent->GetName() << "> is an unsigned_char" << eom); - string str = (aComponent->GetName() + '\t'); - - for (char& it : str) - fWriter->TextFile()->File()->put(it); + fLabel += (aComponent->GetName() + '\t'); - if (aTrack == 0) { - auto* obj = new OutputObjectASCII(aComponent, "unsigned char", fWriter->Precision()); - fOutputObjectASCIIs.push_back(obj); - fComponents.push_back(aComponent); - } + auto* obj = new OutputObjectASCII(aComponent, "unsigned char", aPrecision); + fOutputObjectASCIIs.push_back(obj); + fComponents.push_back(aComponent); + return; } auto* tChar = aComponent->As(); if (tChar != nullptr) { wtrmsg_debug(" object <" << aComponent->GetName() << "> is a char" << eom); - string str = (aComponent->GetName() + '\t'); - - for (char& it : str) - fWriter->TextFile()->File()->put(it); + fLabel += (aComponent->GetName() + '\t'); - if (aTrack == 0) { - auto* obj = new OutputObjectASCII(aComponent, "char", fWriter->Precision()); - fOutputObjectASCIIs.push_back(obj); - fComponents.push_back(aComponent); - } + auto* obj = new OutputObjectASCII(aComponent, "char", aPrecision); + fOutputObjectASCIIs.push_back(obj); + fComponents.push_back(aComponent); + return; } auto* tUShort = aComponent->As(); if (tUShort != nullptr) { wtrmsg_debug(" object <" << aComponent->GetName() << "> is an unsigned_short" << eom); - string str = (aComponent->GetName() + '\t'); + fLabel += (aComponent->GetName() + '\t'); - for (char& it : str) - fWriter->TextFile()->File()->put(it); - - if (aTrack == 0) { - auto* obj = new OutputObjectASCII(aComponent, "unsigned short", fWriter->Precision()); - fOutputObjectASCIIs.push_back(obj); - fComponents.push_back(aComponent); - } + auto* obj = new OutputObjectASCII(aComponent, "unsigned short", aPrecision); + fOutputObjectASCIIs.push_back(obj); + fComponents.push_back(aComponent); + return; } auto* tShort = aComponent->As(); if (tShort != nullptr) { wtrmsg_debug(" object <" << aComponent->GetName() << "> is a short" << eom); - string str = (aComponent->GetName() + '\t'); - - for (char& it : str) - fWriter->TextFile()->File()->put(it); + fLabel += (aComponent->GetName() + '\t'); - if (aTrack == 0) { - auto* obj = new OutputObjectASCII(aComponent, "short", fWriter->Precision()); - fOutputObjectASCIIs.push_back(obj); - fComponents.push_back(aComponent); - } + auto* obj = new OutputObjectASCII(aComponent, "short", aPrecision); + fOutputObjectASCIIs.push_back(obj); + fComponents.push_back(aComponent); + return; } auto* tUInt = aComponent->As(); if (tUInt != nullptr) { wtrmsg_debug(" object <" << aComponent->GetName() << "> is a unsigned_int" << eom); - string str = (aComponent->GetName() + '\t'); - - for (char& it : str) - fWriter->TextFile()->File()->put(it); + fLabel += (aComponent->GetName() + '\t'); - if (aTrack == 0) { - auto* obj = new OutputObjectASCII(aComponent, "unsigned int", fWriter->Precision()); - fOutputObjectASCIIs.push_back(obj); - fComponents.push_back(aComponent); - } + auto* obj = new OutputObjectASCII(aComponent, "unsigned int", aPrecision); + fOutputObjectASCIIs.push_back(obj); + fComponents.push_back(aComponent); + return; } auto* tInt = aComponent->As(); if (tInt != nullptr) { wtrmsg_debug(" object <" << aComponent->GetName() << "> is an int" << eom); - string str = (aComponent->GetName() + '\t'); + fLabel += (aComponent->GetName() + '\t'); - for (char& it : str) - fWriter->TextFile()->File()->put(it); - - if (aTrack == 0) { - auto* obj = new OutputObjectASCII(aComponent, "int", fWriter->Precision()); - fOutputObjectASCIIs.push_back(obj); - fComponents.push_back(aComponent); - } + auto* obj = new OutputObjectASCII(aComponent, "int", aPrecision); + fOutputObjectASCIIs.push_back(obj); + fComponents.push_back(aComponent); + return; } auto* tULong = aComponent->As(); if (tULong != nullptr) { wtrmsg_debug(" object <" << aComponent->GetName() << "> is an unsigned_long" << eom); - string str = (aComponent->GetName() + '\t'); - - for (char& it : str) - fWriter->TextFile()->File()->put(it); + fLabel += (aComponent->GetName() + '\t'); - if (aTrack == 0) { - auto* obj = new OutputObjectASCII(aComponent, "unsigned long", fWriter->Precision()); - fOutputObjectASCIIs.push_back(obj); - fComponents.push_back(aComponent); - } + auto* obj = new OutputObjectASCII(aComponent, "unsigned long", aPrecision); + fOutputObjectASCIIs.push_back(obj); + fComponents.push_back(aComponent); + return; } auto* tLong = aComponent->As(); if (tLong != nullptr) { wtrmsg_debug(" object <" << aComponent->GetName() << "> is a long" << eom); - string str = (aComponent->GetName() + '\t'); - - for (char& it : str) - fWriter->TextFile()->File()->put(it); + fLabel += (aComponent->GetName() + '\t'); - if (aTrack == 0) { - auto* obj = new OutputObjectASCII(aComponent, "long", fWriter->Precision()); - fOutputObjectASCIIs.push_back(obj); - fComponents.push_back(aComponent); - } + auto* obj = new OutputObjectASCII(aComponent, "long", aPrecision); + fOutputObjectASCIIs.push_back(obj); + fComponents.push_back(aComponent); + return; } auto* tLongLong = aComponent->As(); if (tLongLong != nullptr) { wtrmsg_debug(" object <" << aComponent->GetName() << "> is a long_long" << eom); - string str = (aComponent->GetName() + '\t'); + fLabel += (aComponent->GetName() + '\t'); - for (char& it : str) - fWriter->TextFile()->File()->put(it); - - if (aTrack == 0) { - auto* obj = new OutputObjectASCII(aComponent, "long_long", fWriter->Precision()); - fOutputObjectASCIIs.push_back(obj); - fComponents.push_back(aComponent); - } + auto* obj = new OutputObjectASCII(aComponent, "long_long", aPrecision); + fOutputObjectASCIIs.push_back(obj); + fComponents.push_back(aComponent); + return; } auto* tFloat = aComponent->As(); if (tFloat != nullptr) { wtrmsg_debug(" object <" << aComponent->GetName() << "> is a float" << eom); - string str = (aComponent->GetName() + '\t'); - - for (char& it : str) - fWriter->TextFile()->File()->put(it); - - if (aTrack == 0) { - auto* obj = new OutputObjectASCII(aComponent, "float", fWriter->Precision()); - fOutputObjectASCIIs.push_back(obj); - fComponents.push_back(aComponent); - } + fLabel += (aComponent->GetName() + '\t'); + + auto* obj = new OutputObjectASCII(aComponent, "float", aPrecision); + fOutputObjectASCIIs.push_back(obj); + fComponents.push_back(aComponent); + return; } auto* tDouble = aComponent->As(); if (tDouble != nullptr) { wtrmsg_debug(" object <" << aComponent->GetName() << "> is a double" << eom); - string str = (aComponent->GetName() + '\t'); - - for (char& it : str) - fWriter->TextFile()->File()->put(it); - - if (aTrack == 0) { - auto* obj = new OutputObjectASCII(aComponent, "double", fWriter->Precision()); - fOutputObjectASCIIs.push_back(obj); - fComponents.push_back(aComponent); - } + fLabel += (aComponent->GetName() + '\t'); + + auto* obj = new OutputObjectASCII(aComponent, "double", aPrecision); + fOutputObjectASCIIs.push_back(obj); + fComponents.push_back(aComponent); + return; } wtrmsg(eError) << "ASCII writer cannot add object <" << aComponent->GetName() << ">" << eom; + fLabel += "error"; return; } @@ -514,8 +446,10 @@ void KSWriteASCII::ExecuteRun() if (fStepIndex != 0) fRunLastStepIndex = fStepIndex - 1; + Write("run\t"); for (auto& activeRunComponent : fActiveRunComponents) Write(activeRunComponent.second->ValuesAsString()); + Write("\n"); fRunIndex++; fRunFirstEventIndex = fEventIndex; @@ -535,8 +469,10 @@ void KSWriteASCII::ExecuteEvent() if (fStepIndex != 0) fEventLastStepIndex = fStepIndex - 1; + Write("event\t"); for (auto& activeEventComponent : fActiveEventComponents) Write(activeEventComponent.second->ValuesAsString()); + Write("\n"); fEventIndex++; fEventFirstTrackIndex = fTrackIndex; @@ -551,33 +487,16 @@ void KSWriteASCII::ExecuteTrack() if (fStepIndex != 0) fTrackLastStepIndex = fStepIndex - 1; - fTextFile->File()->put('\n'); + Write("track\t"); for (auto& activeTrackComponent : fActiveTrackComponents) Write(activeTrackComponent.second->ValuesAsString()); + Write("\n"); wtrmsg(eNormal) << "ASCII output was written to file <" << fTextFile->GetName() << ">" << eom; fTextFile->Close(); delete fTextFile; - - // new output file - - fTextFile = MakeOutputFile(fTrackIndex + 1); - if (fTextFile->Open(KFile::eWrite) == true) { - // do nothing here - } - else { - wtrmsg(eError) << "could not open ASCII output file" << eom; - } - - ComponentIt tIt; - - for (tIt = fTrackComponents.begin(); tIt != fTrackComponents.end(); tIt++) - tIt->second->MakeTitle(tIt->first, 0); - - fTextFile->File()->put('\n'); - for (tIt = fStepComponents.begin(); tIt != fStepComponents.end(); tIt++) - tIt->second->MakeTitle(tIt->first, 1); + fTextFile = nullptr; fTrackIndex++; fTrackFirstStepIndex = fStepIndex; @@ -593,13 +512,14 @@ void KSWriteASCII::ExecuteStep() return; } - fTextFile->File()->put('\n'); + Write("step\t"); if (fStepComponent == true) { wtrmsg_debug("ASCII writer <" << GetName() << "> is filling a step" << eom); for (auto& activeStepComponent : fActiveStepComponents) Write(activeStepComponent.second->ValuesAsString()); } + Write("\n"); fStepIndex++; fStepIterationIndex++; @@ -617,7 +537,7 @@ void KSWriteASCII::AddRunComponent(KSComponent* aComponent) fKey = aComponent->GetName(); - auto* tRunData = new Data(aComponent, this); + auto* tRunData = new Data(aComponent, Precision()); tIt = fRunComponents.insert(ComponentEntry(aComponent, tRunData)).first; } @@ -649,7 +569,7 @@ void KSWriteASCII::AddEventComponent(KSComponent* aComponent) fKey = aComponent->GetName(); - auto* tEventData = new Data(aComponent, this); + auto* tEventData = new Data(aComponent, Precision()); tIt = fEventComponents.insert(ComponentEntry(aComponent, tEventData)).first; } @@ -682,7 +602,7 @@ void KSWriteASCII::AddTrackComponent(KSComponent* aComponent) fKey = aComponent->GetName(); - auto* tTrackData = new Data(aComponent, this); + auto* tTrackData = new Data(aComponent, Precision()); tIt = fTrackComponents.insert(ComponentEntry(aComponent, tTrackData)).first; } @@ -717,7 +637,7 @@ void KSWriteASCII::AddStepComponent(KSComponent* aComponent) fKey = aComponent->GetName(); - auto* tStepData = new Data(aComponent, this); + auto* tStepData = new Data(aComponent, Precision()); tIt = fStepComponents.insert(ComponentEntry(aComponent, tStepData)).first; } @@ -747,15 +667,6 @@ void KSWriteASCII::InitializeComponent() { wtrmsg_debug("starting ASCII writer" << eom); - fTextFile = MakeOutputFile(fTrackIndex); - - if (fTextFile->Open(KFile::eWrite) == true) { - // do nothing here - } - else { - wtrmsg(eError) << "could not open ASCII output file" << eom; - } - return; } @@ -770,14 +681,17 @@ void KSWriteASCII::DeinitializeComponent() for (tIt = fStepComponents.begin(); tIt != fStepComponents.end(); tIt++) delete tIt->second; - fTextFile->Close(); + if (fTextFile) { + fTextFile->Close(); - delete fTextFile; + delete fTextFile; + fTextFile = nullptr; + } return; } -KTextFile* KSWriteASCII::MakeOutputFile(int anIndex) const +void KSWriteASCII::MakeOutputFile(int anIndex) { stringstream s; s << fBase << "_Track" << anIndex << +".txt"; @@ -787,7 +701,39 @@ KTextFile* KSWriteASCII::MakeOutputFile(int anIndex) const #ifdef Kassiopeia_USE_BOOST KPathUtils::MakeDirectory(tPath); #endif - return KTextFile::CreateOutputTextFile(tPath, tBase); + + fTextFile = KTextFile::CreateOutputTextFile(tPath, tBase); + + // Test file + if (fTextFile->Open(KFile::eWrite) == true) { + // do nothing here + } + else { + wtrmsg(eError) << "could not open ASCII output file" << eom; + } + + //Write header + ComponentIt tIt; + + Write("# Run: "); + for (tIt = fActiveRunComponents.begin(); tIt != fActiveRunComponents.end(); tIt++) + Write(tIt->second->Label()); + Write('\n'); + + Write("# Event: "); + for (tIt = fActiveEventComponents.begin(); tIt != fActiveEventComponents.end(); tIt++) + Write(tIt->second->Label()); + Write('\n'); + + Write("# Track: "); + for (tIt = fActiveTrackComponents.begin(); tIt != fActiveTrackComponents.end(); tIt++) + Write(tIt->second->Label()); + Write('\n'); + + Write("# Step: "); + for (tIt = fActiveStepComponents.begin(); tIt != fActiveStepComponents.end(); tIt++) + Write(tIt->second->Label()); + Write('\n'); } STATICINT sKSWriteASCIIDict =