Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/Plugins/SimplnxCore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ set(FilterList
WriteStlFileFilter
WriteVtkRectilinearGridFilter
WriteVtkStructuredPointsFilter
ReadNotesFileFilter
)

set(ActionList
Expand Down Expand Up @@ -316,6 +317,7 @@ set(AlgorithmList
WriteStlFile
WriteVtkRectilinearGrid
WriteVtkStructuredPoints
ReadNotesFile
)

create_simplnx_plugin(NAME ${PLUGIN_NAME}
Expand Down
27 changes: 27 additions & 0 deletions src/Plugins/SimplnxCore/docs/ReadNotesFileFilter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Read Notes File

## Group (Subgroup)

Import

## Description

This **Filter** is primarily intended to store notes about the data, experiment, analysis or sample prep. While in theory
one could read any kind of file, the underlying data is stored in a string array.


% Auto generated parameter table will be inserted here

## Reference


## Example Pipelines


## License & Copyright

Please see the description file distributed with this plugin.

## DREAM3D Mailing Lists

If you need help, need to file a bug report or want to request a new feature, please head over to the [DREAM3DNX-Issues](https://github.com/BlueQuartzSoftware/DREAM3DNX-Issues/discussions) GitHub site where the community of DREAM3D-NX users can help answer your questions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include "ReadNotesFile.hpp"

#include "simplnx/DataStructure/DataArray.hpp"
#include "simplnx/DataStructure/StringArray.hpp"

#include <filesystem>
#include <vector>

namespace fs = std::filesystem;
using namespace nx::core;

// -----------------------------------------------------------------------------
ReadNotesFile::ReadNotesFile(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, ReadNotesFileInputValues* inputValues)
: m_DataStructure(dataStructure)
, m_InputValues(inputValues)
, m_ShouldCancel(shouldCancel)
, m_MessageHandler(mesgHandler)
{
}

// -----------------------------------------------------------------------------
ReadNotesFile::~ReadNotesFile() noexcept = default;

// -----------------------------------------------------------------------------
Result<> ReadNotesFile::operator()()
{
std::vector<uint8_t> buffer;

// Read the file into a uint8 vector
try
{
// Check if the path points to a regular file
if(fs::is_regular_file(m_InputValues->InputFilePath))
{
// Get the size of the file in bytes
usize size_in_bytes = fs::file_size(m_InputValues->InputFilePath);

// 1. Open the file in binary mode
// std::ios::ate seeks to the end of the file immediately after opening
std::ifstream input_file(m_InputValues->InputFilePath, std::ios_base::in | std::ios_base::binary);

// 2. Check if the file opened successfully
if(!input_file.is_open())
{
std::cerr << "Error: Unable to open file " << m_InputValues->InputFilePath << std::endl;
return {MakeErrorResult(-38202, fmt::format("Could not open input file '{}'", m_InputValues->InputFilePath.string()))};
}

// 5. Resize the vector to the file size to allocate the required storage
buffer.resize(size_in_bytes);

// 6. Read the entire file content into the vector's underlying data array
// reinterpret_cast is used to treat uint8_t* as char* for the read function
input_file.read(reinterpret_cast<char*>(buffer.data()), size_in_bytes);

// 7. Close the file (optional, as the ifstream destructor will do this)
input_file.close();
}
else
{
return {MakeErrorResult<>(-38200, fmt::format("The path '{}' does not point to a regular file, or the file does not exist.", m_InputValues->InputFilePath.string()))};
}
} catch(fs::filesystem_error const& ex)
{
// Handle potential errors (e.g., file not found, permission denied)
return {MakeErrorResult<>(-38201, fmt::format("Filesystem error for file '{}'\nOperating System returned error '{}'", m_InputValues->InputFilePath.string(), ex.what()))};
}

auto& outputArrayRef = m_DataStructure.getDataRefAs<StringArray>(m_InputValues->CreatedDataPath);
std::string bufAsString(buffer.begin(), buffer.end());
outputArrayRef.setValue(0, bufAsString);

return {};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once

#include "SimplnxCore/SimplnxCore_export.hpp"

#include "simplnx/DataStructure/DataPath.hpp"
#include "simplnx/DataStructure/DataStructure.hpp"
#include "simplnx/Filter/Actions/CreateStringArrayAction.hpp"
#include "simplnx/Filter/IFilter.hpp"
#include "simplnx/Parameters/FileSystemPathParameter.hpp"

namespace nx::core
{

struct SIMPLNXCORE_EXPORT ReadNotesFileInputValues
{
FileSystemPathParameter::ValueType InputFilePath;
DataPath CreatedDataPath;
};

/**
* @class ReadNotesFile
* @brief This algorithm implements support code for the ReadNotesFileFilter
*/

class SIMPLNXCORE_EXPORT ReadNotesFile
{
public:
ReadNotesFile(DataStructure& dataStructure, const IFilter::MessageHandler& mesgHandler, const std::atomic_bool& shouldCancel, ReadNotesFileInputValues* inputValues);
~ReadNotesFile() noexcept;

ReadNotesFile(const ReadNotesFile&) = delete;
ReadNotesFile(ReadNotesFile&&) noexcept = delete;
ReadNotesFile& operator=(const ReadNotesFile&) = delete;
ReadNotesFile& operator=(ReadNotesFile&&) noexcept = delete;

Result<> operator()();

private:
DataStructure& m_DataStructure;
const ReadNotesFileInputValues* m_InputValues = nullptr;
const std::atomic_bool& m_ShouldCancel;
const IFilter::MessageHandler& m_MessageHandler;
};

} // namespace nx::core
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#include "ReadNotesFileFilter.hpp"

#include "CopyDataObjectFilter.hpp"
#include "SimplnxCore/Filters/Algorithms/ReadNotesFile.hpp"

#include "simplnx/DataStructure/DataPath.hpp"
#include "simplnx/Filter/Actions/CreateArrayAction.hpp"
#include "simplnx/Filter/Actions/CreateStringArrayAction.hpp"
#include "simplnx/Filter/Actions/EmptyAction.hpp"
#include "simplnx/Parameters/ArrayCreationParameter.hpp"
#include "simplnx/Parameters/FileSystemPathParameter.hpp"

#include <filesystem>
#include <vector>

namespace fs = std::filesystem;
using namespace nx::core;

namespace nx::core
{
//------------------------------------------------------------------------------
std::string ReadNotesFileFilter::name() const
{
return FilterTraits<ReadNotesFileFilter>::name.str();
}

//------------------------------------------------------------------------------
std::string ReadNotesFileFilter::className() const
{
return FilterTraits<ReadNotesFileFilter>::className;
}

//------------------------------------------------------------------------------
Uuid ReadNotesFileFilter::uuid() const
{
return FilterTraits<ReadNotesFileFilter>::uuid;
}

//------------------------------------------------------------------------------
std::string ReadNotesFileFilter::humanName() const
{
return "Read Notes File";
}

//------------------------------------------------------------------------------
std::vector<std::string> ReadNotesFileFilter::defaultTags() const
{
return {className(), "IO", "Input", "Read", "Import", "Notes", "Text"};
}

//------------------------------------------------------------------------------
Parameters ReadNotesFileFilter::parameters() const
{
Parameters params;
// Create the parameter descriptors that are needed for this filter
params.insertSeparator(Parameters::Separator{"Input Parameter(s)"});
params.insert(std::make_unique<FileSystemPathParameter>(k_InputFile_Key, "Input File", "The input text file", fs::path("input.ang"),
FileSystemPathParameter::ExtensionsType{{".txt"}, {".md"}, {".rst"}, {".text"}, {".*"}}, FileSystemPathParameter::PathType::InputFile));
params.insert(std::make_unique<ArrayCreationParameter>(k_DataArrayPath_Key, "Created Array Path", "DataPath or Name for the underlying Data Array", DataPath{}));

return params;
}

//------------------------------------------------------------------------------
IFilter::VersionType ReadNotesFileFilter::parametersVersion() const
{
return 1;
}

//------------------------------------------------------------------------------
IFilter::UniquePointer ReadNotesFileFilter::clone() const
{
return std::make_unique<ReadNotesFileFilter>();
}

//------------------------------------------------------------------------------
IFilter::PreflightResult ReadNotesFileFilter::preflightImpl(const DataStructure& dataStructure, const Arguments& filterArgs, const MessageHandler& messageHandler, const std::atomic_bool& shouldCancel,
const ExecutionContext& executionContext) const
{
auto pInputFileValue = filterArgs.value<FileSystemPathParameter::ValueType>(k_InputFile_Key);
auto arrayPath = filterArgs.value<DataPath>(k_DataArrayPath_Key);
usize size_in_bytes = 0;
try
{
// Check if the path points to a regular file
if(fs::is_regular_file(pInputFileValue))
{
// Get the size of the file in bytes
size_in_bytes = fs::file_size(pInputFileValue);
}
else
{
return {MakeErrorResult<OutputActions>(-38200, fmt::format("The path '{}' does not point to a regular file, or the file does not exist.", pInputFileValue.string()))};
}
} catch(fs::filesystem_error const& ex)
{
// Handle potential errors (e.g., file not found, permission denied)
return {MakeErrorResult<OutputActions>(-38201, fmt::format("Filesystem error for file '{}'\nOperating System returned error '{}'", pInputFileValue.string(), ex.what()))};
}

// Declare the preflightResult variable that will be populated with the results
// of the preflight. The PreflightResult type contains the output Actions and
// any preflight updated values that you want to be displayed to the user, typically
// through a user interface (UI).
PreflightResult preflightResult;

// If your filter is making structural changes to the DataStructure then the filter
// is going to create OutputActions subclasses that need to be returned. This will
// store those actions.
Result<OutputActions> resultOutputActions;
ShapeType tupleDims = {1};
resultOutputActions.value().appendAction(std::make_unique<CreateStringArrayAction>(tupleDims, arrayPath));

// If your filter is going to pass back some `preflight updated values` then this is where you
// would create the code to store those values in the appropriate object. Note that we
// in line creating the pair (NOT a std::pair<>) of Key:Value that will get stored in
// the std::vector<PreflightValue> object.
std::vector<PreflightValue> preflightUpdatedValues;

return {std::move(resultOutputActions), std::move(preflightUpdatedValues)};
}

//------------------------------------------------------------------------------
Result<> ReadNotesFileFilter::executeImpl(DataStructure& dataStructure, const Arguments& filterArgs, const PipelineFilter* pipelineNode, const MessageHandler& messageHandler,
const std::atomic_bool& shouldCancel, const ExecutionContext& executionContext) const
{
ReadNotesFileInputValues inputValues;

inputValues.InputFilePath = filterArgs.value<FileSystemPathParameter::ValueType>(k_InputFile_Key);
inputValues.CreatedDataPath = filterArgs.value<DataPath>(k_DataArrayPath_Key);

return ReadNotesFile(dataStructure, messageHandler, shouldCancel, &inputValues)();
}

namespace
{
namespace SIMPL
{

// TODO: PARAMETER_JSON_CONSTANTS
} // namespace SIMPL
} // namespace

//------------------------------------------------------------------------------
Result<Arguments> ReadNotesFileFilter::FromSIMPLJson(const nlohmann::json& json)
{
Arguments args = ReadNotesFileFilter().getDefaultArguments();

std::vector<Result<>> results;

/* This is a NEW filter and not ported so this section does not matter */

Result<> conversionResult = MergeResults(std::move(results));

return ConvertResultTo<Arguments>(std::move(conversionResult), std::move(args));
}

} // namespace nx::core
Loading
Loading