SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
SDDSTransform.cc File Reference

Detailed Description

Typed layout and page transformations for the C++17 SDDS interface.

Implements checked scalar and vector conversions, layout editing, row masks and views, page filtering and projection, unit conversion, and streaming transformed copies.

License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.

Definition in file SDDSTransform.cc.

#include "SDDS.hpp"
#include <algorithm>
#include <cmath>
#include <limits>
#include <type_traits>

Go to the source code of this file.

Functions

Scalar sdds::convertScalar (const Scalar &value, Type target, RoundingMode rounding)
 
Values sdds::convertValues (const Values &values, Type target, RoundingMode rounding)
 
Page sdds::convertUnits (const Page &page, FieldKind kind, std::string_view name, std::optional< std::string > units, long double factor)
 
void sdds::copyDataset (Reader &reader, const std::filesystem::path &output, CopyOptions options)
 

Function Documentation

◆ convertScalar()

Scalar sdds::convertScalar ( const Scalar & value,
Type target,
RoundingMode rounding )

Definition at line 233 of file SDDSTransform.cc.

233 {
234 if (target == Type::String) {
235 if (const auto *text = std::get_if<std::string>(&value))
236 return *text;
237 typeError("numeric values cannot be implicitly converted to strings");
238 }
239 switch (target) {
240 case Type::LongDouble: return convertTo<long double>(value, rounding);
241 case Type::Double: return convertTo<double>(value, rounding);
242 case Type::Float: return convertTo<float>(value, rounding);
243 case Type::Int64: return convertTo<std::int64_t>(value, rounding);
244 case Type::UInt64: return convertTo<std::uint64_t>(value, rounding);
245 case Type::Int32: return convertTo<std::int32_t>(value, rounding);
246 case Type::UInt32: return convertTo<std::uint32_t>(value, rounding);
247 case Type::Int16: return convertTo<std::int16_t>(value, rounding);
248 case Type::UInt16: return convertTo<std::uint16_t>(value, rounding);
249 case Type::Character: return convertTo<char>(value, rounding);
250 case Type::String: break;
251 }
252 typeError("unknown conversion target");
253}

◆ convertUnits()

Page sdds::convertUnits ( const Page & page,
FieldKind kind,
std::string_view name,
std::optional< std::string > units,
long double factor )

Definition at line 430 of file SDDSTransform.cc.

431 {
432 Layout changed = page.layout();
433 if (!std::isfinite(factor)) typeError("unit conversion factor must be finite");
434 switch (kind) {
435 case FieldKind::Parameter: changed.parameters.at(changed.parameterIndex(name)).units = units; break;
436 case FieldKind::Array: changed.arrays.at(changed.arrayIndex(name)).units = units; break;
437 case FieldKind::Column: changed.columns.at(changed.columnIndex(name)).units = units; break;
438 }
439 auto layout = std::make_shared<const Layout>(LayoutBuilder(std::move(changed)).build());
440 Page result(layout, LoadMode::None);
441 result.maxTransformationElements_ = page.maxTransformationElements_;
442 result.number_ = page.number_;
443 result.recovered_ = page.recovered_;
444 result.rowCount_ = page.rowCount_;
445 for (std::size_t index = 0; index < page.parameters_.size(); ++index) {
446 if (!page.parameterLoaded(index)) continue;
447 Scalar value = page.parameters_[index];
448 if (kind == FieldKind::Parameter && page.layout().parameters[index].name == name)
449 value = scaledScalar(value, page.layout().parameters[index].type, factor);
450 result.setParameter(index, std::move(value));
451 }
452 for (std::size_t index = 0; index < page.arrays_.size(); ++index) {
453 if (!page.arrayLoaded(index)) continue;
454 ArrayData value = page.arrays_[index];
455 if (kind == FieldKind::Array && page.layout().arrays[index].name == name)
456 value.values = scaledValues(value.values, page.layout().arrays[index].type, factor);
457 result.setArray(index, std::move(value));
458 }
459 for (std::size_t index = 0; index < page.columns_.size(); ++index) {
460 if (!page.columnLoaded(index)) continue;
461 Values value = page.columns_[index];
462 if (kind == FieldKind::Column && page.layout().columns[index].name == name)
463 value = scaledValues(value, page.layout().columns[index].type, factor);
464 result.setColumn(index, std::move(value));
465 }
466 result.rowCount_ = page.rowCount_;
467 return result;
468}

◆ convertValues()

Values sdds::convertValues ( const Values & values,
Type target,
RoundingMode rounding )

Definition at line 255 of file SDDSTransform.cc.

255 {
256 if (typeOf(values) == target)
257 return values;
258 Values result = emptyValues(target);
259 const std::size_t count = std::visit([](const auto &items) { return items.size(); }, values);
260 for (std::size_t index = 0; index < count; ++index)
261 appendScalar(result, convertScalar(scalarAt(values, index), target, rounding));
262 return result;
263}

◆ copyDataset()

void sdds::copyDataset ( Reader & reader,
const std::filesystem::path & output,
CopyOptions options )

Definition at line 470 of file SDDSTransform.cc.

470 {
471 Layout outputLayout = options.transformLayout ? options.transformLayout(reader.layout())
472 : reader.layout();
473 auto shared = std::make_shared<const Layout>(outputLayout);
474 Writer writer = Writer::create(output, outputLayout, options.writer);
475 while (auto page = reader.next(options.read)) {
476 if (options.transformPage) {
477 auto transformed = options.transformPage(std::move(*page), shared);
478 if (transformed) writer.write(std::move(*transformed));
479 } else {
480 writer.write(std::move(*page));
481 }
482 }
483 writer.close();
484}