src/modules/TextWriter/TextWriterModule.cpp
Implementation of ROOT data file writer module. More…
Detailed Description
Implementation of ROOT data file writer module.
Copyright: Copyright (c) 2018-2024 CERN and the Allpix Squared authors. This software is distributed under the terms of the MIT License, copied verbatim in the file “LICENSE.md”. In applying this license, CERN does not waive the privileges and immunities granted to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. SPDX-License-Identifier: MIT
Source code
#include "TextWriterModule.hpp"
#include <fstream>
#include <string>
#include <utility>
#include <TBranchElement.h>
#include <TClass.h>
#include "core/config/ConfigReader.hpp"
#include "core/utils/log.h"
#include "core/utils/type.h"
#include "objects/Object.hpp"
#include "objects/objects.h"
using namespace allpix;
TextWriterModule::TextWriterModule(Configuration& config, Messenger* messenger, GeometryManager*)
: SequentialModule(config), messenger_(messenger) {
// Enable multithreading of this module if multithreading is enabled
allow_multithreading();
// Bind to all messages with filter
messenger_->registerFilter(this, &TextWriterModule::filter);
}
void TextWriterModule::initialize() {
// Create output file
output_file_name_ = createOutputFile(config_.get<std::string>("file_name", "data"), "txt", true);
output_file_ = std::make_unique<std::ofstream>(output_file_name_);
*output_file_ << "# Allpix Squared ASCII data - https://cern.ch/allpix-squared" << std::endl << std::endl;
// Read include and exclude list
if(config_.has("include") && config_.has("exclude")) {
throw InvalidValueError(config_, "exclude", "include and exclude parameter are mutually exclusive");
} else if(config_.has("include")) {
auto inc_arr = config_.getArray<std::string>("include");
include_.insert(inc_arr.begin(), inc_arr.end());
} else if(config_.has("exclude")) {
auto exc_arr = config_.getArray<std::string>("exclude");
exclude_.insert(exc_arr.begin(), exc_arr.end());
}
}
bool TextWriterModule::filter(const std::shared_ptr<BaseMessage>& message, const std::string& message_name) const { // NOLINT
try {
const BaseMessage* inst = message.get();
std::string name_str = " without a name";
if(!message_name.empty()) {
name_str = " named " + message_name;
}
LOG(TRACE) << "Text writer received " << allpix::demangle(typeid(*inst).name()) << name_str;
// Get the detector name
std::string detector_name;
if(message->getDetector() != nullptr) {
detector_name = message->getDetector()->getName();
}
// Read the object
auto object_array = message->getObjectArray();
if(!object_array.empty()) {
const Object& first_object = object_array[0];
std::string class_name = allpix::demangle(typeid(first_object).name());
// Check if this message should be kept
if((!include_.empty() && include_.find(class_name) == include_.end()) ||
(!exclude_.empty() && exclude_.find(class_name) != exclude_.end())) {
LOG(TRACE) << "Text writer ignored message with object " << allpix::demangle(typeid(*inst).name())
<< " because it has been excluded or not explicitly included";
return false;
}
return true;
}
} catch(MessageWithoutObjectException& e) {
const BaseMessage* inst = message.get();
LOG(WARNING) << "Text writer cannot process message of type" << allpix::demangle(typeid(*inst).name())
<< " with name " << message_name;
}
return false;
}
void TextWriterModule::run(Event* event) {
auto messages = messenger_->fetchFilteredMessages(this, event);
LOG(TRACE) << "Writing new objects to text file";
// Print the current event:
*output_file_ << "=== " << event->number << " ===" << std::endl;
for(auto& pair : messages) {
auto& message = pair.first;
// Print the current detector:
if(message->getDetector() != nullptr) {
*output_file_ << "--- " << message->getDetector()->getName() << " ---" << std::endl;
} else {
*output_file_ << "--- <global> ---" << std::endl;
}
for(auto& object : message->getObjectArray()) {
// Print the object's ASCII representation:
*output_file_ << object << std::endl;
write_cnt_++;
}
msg_cnt_++;
}
}
void TextWriterModule::finalize() {
// Finish writing to output file
*output_file_ << "# " << write_cnt_ << " objects from " << msg_cnt_ << " messages" << std::endl;
// Print statistics
LOG(STATUS) << "Wrote " << write_cnt_ << " objects from " << msg_cnt_ << " messages to file:" << std::endl
<< output_file_name_;
}
Updated on 2024-12-13 at 08:31:37 +0000