use clang-tidy (#59)

* use clang-tidy for Frame.cpp

* fixes for defs.cpp

* clang-tidy 6/45

* clang-tidy for core

* clang-tidy fixes: for hpp File,FileInterface,SubFile.cpp

* ci fixes

* fix build errors

* fix clang-tidy command ci

* fix clang-tidy ci

* clang-tidy for rawfile.cpp

* clang-tidy numpy helpers

* fix ci

* clang-tidy file_io

* clang-tidy file_io and core working

* zmqheader

* clagn-tidy: network_io,file_io,core

* clang-tidy working

* format

---------

Co-authored-by: Bechir <bechir.brahem420@gmail.com>
This commit is contained in:
Bechir Braham
2024-04-12 17:35:36 +02:00
committed by GitHub
parent eb7108b837
commit 9dfd388927
44 changed files with 1055 additions and 470 deletions

493
.clang-tidy Normal file
View File

@ -0,0 +1,493 @@
---
Checks: '
# DISABLE CHECKS:
# readability-magic-numbers
# - misc-include-cleaner (issues with includes from associated header files)
# (should fixed in 18.1.0 release)
# - cppcoreguidelines-avoid-magic-numbers
# - cppcoreguidelines-owning-memory
# - bugprone-easily-swappable-parameters
# - cppcoreguidelines-non-private-member-variables-in-classes
# abseil-cleanup-ctad
# abseil-duration-addition
# abseil-duration-comparison
# abseil-duration-conversion-cast
# abseil-duration-division
# abseil-duration-factory-float
# abseil-duration-factory-scale
# abseil-duration-subtraction
# abseil-duration-unnecessary-conversion
# abseil-faster-strsplit-delimiter
# abseil-no-internal-dependencies
# abseil-no-namespace
# abseil-redundant-strcat-calls
# abseil-str-cat-append
# abseil-string-find-startswith
# abseil-string-find-str-contains
# abseil-time-comparison
# abseil-time-subtraction
# abseil-upgrade-duration-conversions
android-cloexec-accept
cppcoreguidelines-special-member-functions
hicpp-special-member-functions
android-cloexec-accept4
android-cloexec-creat
android-cloexec-dup
android-cloexec-epoll-create
android-cloexec-epoll-create1
android-cloexec-inotify-init
android-cloexec-inotify-init1
android-cloexec-memfd-create
android-cloexec-open
android-cloexec-pipe
android-cloexec-pipe2
android-cloexec-socket
android-comparison-in-temp-failure-retry
boost-use-to-string
bugprone-argument-comment
bugprone-assert-side-effect
bugprone-assignment-in-if-condition
bugprone-bad-signal-to-kill-thread
bugprone-bool-pointer-implicit-conversion
bugprone-branch-clone
bugprone-copy-constructor-init
bugprone-dangling-handle
bugprone-dynamic-static-initializers
bugprone-empty-catch
bugprone-exception-escape
bugprone-fold-init-type
bugprone-forward-declaration-namespace
bugprone-forwarding-reference-overload
bugprone-implicit-widening-of-multiplication-result
bugprone-inaccurate-erase
bugprone-incorrect-roundings
bugprone-infinite-loop
bugprone-integer-division
bugprone-lambda-function-name
bugprone-macro-parentheses
bugprone-macro-repeated-side-effects
bugprone-misplaced-operator-in-strlen-in-alloc
bugprone-misplaced-pointer-arithmetic-in-alloc
bugprone-misplaced-widening-cast
bugprone-move-forwarding-reference
bugprone-multiple-new-in-one-expression
bugprone-multiple-statement-macro
bugprone-narrowing-conversions
bugprone-no-escape
bugprone-non-zero-enum-to-bool-conversion
bugprone-not-null-terminated-result
bugprone-parent-virtual-call
bugprone-posix-return
bugprone-redundant-branch-condition
bugprone-reserved-identifier
bugprone-shared-ptr-array-mismatch
bugprone-signal-handler
bugprone-signed-char-misuse
bugprone-sizeof-container
bugprone-sizeof-expression
bugprone-spuriously-wake-up-functions
bugprone-standalone-empty
bugprone-string-constructor
bugprone-string-integer-assignment
bugprone-string-literal-with-embedded-nul
bugprone-stringview-nullptr
bugprone-suspicious-enum-usage
bugprone-suspicious-include
bugprone-suspicious-memory-comparison
bugprone-suspicious-memset-usage
bugprone-suspicious-missing-comma
bugprone-suspicious-realloc-usage
bugprone-suspicious-semicolon
bugprone-suspicious-string-compare
bugprone-swapped-arguments
bugprone-switch-missing-default-case
bugprone-terminating-continue
bugprone-throw-keyword-missing
bugprone-too-small-loop-variable
bugprone-unchecked-optional-access
bugprone-undefined-memory-manipulation
bugprone-undelegated-constructor
bugprone-unhandled-exception-at-new
bugprone-unhandled-self-assignment
bugprone-unique-ptr-array-mismatch
bugprone-unsafe-functions
bugprone-unused-raii
bugprone-unused-return-value
bugprone-use-after-move
bugprone-virtual-near-miss
cert-con36-c
cert-con54-cpp
cert-dcl03-c
cert-dcl16-c
cert-dcl21-cpp
cert-dcl37-c
cert-dcl50-cpp
cert-dcl51-cpp
cert-dcl54-cpp
cert-dcl58-cpp
cert-dcl59-cpp
cert-env33-c
cert-err09-cpp
cert-err33-c
cert-err34-c
cert-err52-cpp
cert-err58-cpp
cert-err60-cpp
cert-err61-cpp
cert-exp42-c
cert-fio38-c
cert-flp30-c
cert-flp37-c
cert-mem57-cpp
cert-msc24-c
cert-msc30-c
cert-msc32-c
cert-msc33-c
cert-msc50-cpp
cert-msc51-cpp
cert-msc54-cpp
cert-oop11-cpp
cert-oop54-cpp
cert-oop57-cpp
cert-oop58-cpp
cert-pos44-c
cert-pos47-c
cert-sig30-c
cert-str34-c
clang-analyzer-apiModeling.Errno
clang-analyzer-apiModeling.TrustNonnull
clang-analyzer-apiModeling.TrustReturnsNonnull
clang-analyzer-apiModeling.google.GTest
clang-analyzer-apiModeling.llvm.CastValue
clang-analyzer-apiModeling.llvm.ReturnValue
clang-analyzer-core.CallAndMessage
clang-analyzer-core.CallAndMessageModeling
clang-analyzer-core.DivideZero
clang-analyzer-core.DynamicTypePropagation
clang-analyzer-core.NonNullParamChecker
clang-analyzer-core.NonnilStringConstants
clang-analyzer-core.NullDereference
clang-analyzer-core.StackAddrEscapeBase
clang-analyzer-core.StackAddressEscape
clang-analyzer-core.UndefinedBinaryOperatorResult
clang-analyzer-core.VLASize
clang-analyzer-core.builtin.BuiltinFunctions
clang-analyzer-core.builtin.NoReturnFunctions
clang-analyzer-core.uninitialized.ArraySubscript
clang-analyzer-core.uninitialized.Assign
clang-analyzer-core.uninitialized.Branch
clang-analyzer-core.uninitialized.CapturedBlockVariable
clang-analyzer-core.uninitialized.NewArraySize
clang-analyzer-core.uninitialized.UndefReturn
clang-analyzer-cplusplus.InnerPointer
clang-analyzer-cplusplus.Move
clang-analyzer-cplusplus.NewDelete
clang-analyzer-cplusplus.NewDeleteLeaks
clang-analyzer-cplusplus.PlacementNew
clang-analyzer-cplusplus.PureVirtualCall
clang-analyzer-cplusplus.SelfAssignment
clang-analyzer-cplusplus.SmartPtrModeling
clang-analyzer-cplusplus.StringChecker
clang-analyzer-cplusplus.VirtualCallModeling
clang-analyzer-deadcode.DeadStores
clang-analyzer-fuchsia.HandleChecker
clang-analyzer-nullability.NullPassedToNonnull
clang-analyzer-nullability.NullReturnedFromNonnull
clang-analyzer-nullability.NullabilityBase
clang-analyzer-nullability.NullableDereferenced
clang-analyzer-nullability.NullablePassedToNonnull
clang-analyzer-nullability.NullableReturnedFromNonnull
clang-analyzer-optin.cplusplus.UninitializedObject
clang-analyzer-optin.cplusplus.VirtualCall
clang-analyzer-optin.mpi.MPI-Checker
clang-analyzer-optin.osx.OSObjectCStyleCast
clang-analyzer-optin.osx.cocoa.localizability.EmptyLocalizationContextChecker
clang-analyzer-optin.osx.cocoa.localizability.NonLocalizedStringChecker
clang-analyzer-optin.performance.GCDAntipattern
clang-analyzer-optin.performance.Padding
clang-analyzer-optin.portability.UnixAPI
clang-analyzer-osx.API
clang-analyzer-osx.MIG
clang-analyzer-osx.NSOrCFErrorDerefChecker
clang-analyzer-osx.NumberObjectConversion
clang-analyzer-osx.OSObjectRetainCount
clang-analyzer-osx.ObjCProperty
clang-analyzer-osx.SecKeychainAPI
clang-analyzer-osx.cocoa.AtSync
clang-analyzer-osx.cocoa.AutoreleaseWrite
clang-analyzer-osx.cocoa.ClassRelease
clang-analyzer-osx.cocoa.Dealloc
clang-analyzer-osx.cocoa.IncompatibleMethodTypes
clang-analyzer-osx.cocoa.Loops
clang-analyzer-osx.cocoa.MissingSuperCall
clang-analyzer-osx.cocoa.NSAutoreleasePool
clang-analyzer-osx.cocoa.NSError
clang-analyzer-osx.cocoa.NilArg
clang-analyzer-osx.cocoa.NonNilReturnValue
clang-analyzer-osx.cocoa.ObjCGenerics
clang-analyzer-osx.cocoa.RetainCount
clang-analyzer-osx.cocoa.RetainCountBase
clang-analyzer-osx.cocoa.RunLoopAutoreleaseLeak
clang-analyzer-osx.cocoa.SelfInit
clang-analyzer-osx.cocoa.SuperDealloc
clang-analyzer-osx.cocoa.UnusedIvars
clang-analyzer-osx.cocoa.VariadicMethodTypes
clang-analyzer-osx.coreFoundation.CFError
clang-analyzer-osx.coreFoundation.CFNumber
clang-analyzer-osx.coreFoundation.CFRetainRelease
clang-analyzer-osx.coreFoundation.containers.OutOfBounds
clang-analyzer-osx.coreFoundation.containers.PointerSizedValues
clang-analyzer-security.FloatLoopCounter
clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling
clang-analyzer-security.insecureAPI.SecuritySyntaxChecker
clang-analyzer-security.insecureAPI.UncheckedReturn
clang-analyzer-security.insecureAPI.bcmp
clang-analyzer-security.insecureAPI.bcopy
clang-analyzer-security.insecureAPI.bzero
clang-analyzer-security.insecureAPI.decodeValueOfObjCType
clang-analyzer-security.insecureAPI.getpw
clang-analyzer-security.insecureAPI.gets
clang-analyzer-security.insecureAPI.mkstemp
clang-analyzer-security.insecureAPI.mktemp
clang-analyzer-security.insecureAPI.rand
clang-analyzer-security.insecureAPI.strcpy
clang-analyzer-security.insecureAPI.vfork
clang-analyzer-unix.API
clang-analyzer-unix.DynamicMemoryModeling
clang-analyzer-unix.Malloc
clang-analyzer-unix.MallocSizeof
clang-analyzer-unix.MismatchedDeallocator
clang-analyzer-unix.Vfork
clang-analyzer-unix.cstring.BadSizeArg
clang-analyzer-unix.cstring.CStringModeling
clang-analyzer-unix.cstring.NullArg
clang-analyzer-valist.CopyToSelf
clang-analyzer-valist.Uninitialized
clang-analyzer-valist.Unterminated
clang-analyzer-valist.ValistBase
clang-analyzer-webkit.NoUncountedMemberChecker
clang-analyzer-webkit.RefCntblBaseVirtualDtor
clang-analyzer-webkit.UncountedLambdaCapturesChecker
concurrency-mt-unsafe
concurrency-thread-canceltype-asynchronous
cppcoreguidelines-avoid-c-arrays
cppcoreguidelines-avoid-capturing-lambda-coroutines
cppcoreguidelines-avoid-const-or-ref-data-members
cppcoreguidelines-avoid-do-while
cppcoreguidelines-avoid-goto
cppcoreguidelines-avoid-non-const-global-variables
cppcoreguidelines-avoid-reference-coroutine-parameters
cppcoreguidelines-c-copy-assignment-signature
cppcoreguidelines-explicit-virtual-functions
cppcoreguidelines-init-variables
cppcoreguidelines-interfaces-global-init
cppcoreguidelines-macro-usage
cppcoreguidelines-misleading-capture-default-by-value
cppcoreguidelines-missing-std-forward
cppcoreguidelines-narrowing-conversions
cppcoreguidelines-no-malloc
cppcoreguidelines-noexcept-destructor
cppcoreguidelines-noexcept-move-operations
cppcoreguidelines-noexcept-swap
cppcoreguidelines-prefer-member-initializer
cppcoreguidelines-pro-type-const-cast
cppcoreguidelines-pro-type-cstyle-cast
cppcoreguidelines-pro-type-member-init
cppcoreguidelines-pro-type-static-cast-downcast
cppcoreguidelines-pro-type-union-access
cppcoreguidelines-pro-type-vararg
cppcoreguidelines-rvalue-reference-param-not-moved
cppcoreguidelines-slicing
cppcoreguidelines-use-default-member-init
cppcoreguidelines-virtual-class-destructor
darwin-avoid-spinlock
darwin-dispatch-once-nonstatic
google-build-explicit-make-pair
google-build-namespaces
google-build-using-namespace
google-default-arguments
google-explicit-constructor
google-global-names-in-headers
google-objc-avoid-nsobject-new
google-objc-avoid-throwing-exception
google-objc-function-naming
google-objc-global-variable-declaration
google-readability-avoid-underscore-in-googletest-name
google-readability-casting
google-readability-function-size
google-readability-namespace-comments
google-runtime-int
google-runtime-operator
google-upgrade-googletest-case
hicpp-avoid-c-arrays
hicpp-avoid-goto
hicpp-deprecated-headers
hicpp-exception-baseclass
hicpp-explicit-conversions
hicpp-function-size
hicpp-invalid-access-moved
hicpp-member-init
hicpp-move-const-arg
hicpp-multiway-paths-covered
hicpp-named-parameter
hicpp-new-delete-operators
hicpp-no-assembler
hicpp-no-malloc
hicpp-noexcept-move
hicpp-static-assert
hicpp-undelegated-constructor
hicpp-uppercase-literal-suffix
hicpp-use-auto
hicpp-use-emplace
hicpp-use-equals-default
hicpp-use-equals-delete
hicpp-use-noexcept
hicpp-use-nullptr
hicpp-use-override
hicpp-vararg
linuxkernel-must-check-errs
llvm-else-after-return
llvm-include-order
llvm-namespace-comment
llvm-prefer-isa-or-dyn-cast-in-conditionals
llvm-prefer-register-over-unsigned
llvm-qualified-auto
llvm-twine-local
misc-confusable-identifiers
misc-const-correctness
misc-definitions-in-headers
misc-header-include-cycle
misc-misleading-bidirectional
misc-misleading-identifier
misc-misplaced-const
misc-new-delete-overloads
misc-no-recursion
misc-non-copyable-objects
misc-redundant-expression
misc-static-assert
misc-throw-by-value-catch-by-reference
misc-unconventional-assign-operator
misc-uniqueptr-reset-release
misc-unused-alias-decls
misc-unused-parameters
misc-unused-using-decls
misc-use-anonymous-namespace
modernize-avoid-bind
modernize-avoid-c-arrays
modernize-concat-nested-namespaces
modernize-deprecated-headers
modernize-deprecated-ios-base-aliases
modernize-loop-convert
modernize-macro-to-enum
modernize-make-shared
modernize-make-unique
modernize-pass-by-value
modernize-raw-string-literal
modernize-redundant-void-arg
modernize-replace-auto-ptr
modernize-replace-disallow-copy-and-assign-macro
modernize-replace-random-shuffle
modernize-return-braced-init-list
modernize-shrink-to-fit
modernize-type-traits
modernize-unary-static-assert
modernize-use-auto
modernize-use-bool-literals
modernize-use-default-member-init
modernize-use-emplace
modernize-use-equals-default
modernize-use-equals-delete
modernize-use-noexcept
modernize-use-nullptr
modernize-use-override
modernize-use-std-print
modernize-use-transparent-functors
modernize-use-uncaught-exceptions
modernize-use-using
mpi-buffer-deref
mpi-type-mismatch
objc-assert-equals
objc-avoid-nserror-init
objc-dealloc-in-category
objc-forbidden-subclassing
objc-missing-hash
objc-nsdate-formatter
objc-nsinvocation-argument-lifetime
objc-property-declaration
objc-super-self
openmp-exception-escape
openmp-use-default-none
performance-avoid-endl
performance-faster-string-find
performance-for-range-copy
performance-implicit-conversion-in-loop
performance-inefficient-algorithm
performance-inefficient-string-concatenation
performance-inefficient-vector-operation
performance-move-const-arg
performance-move-constructor-init
performance-no-automatic-move
performance-no-int-to-ptr
performance-noexcept-destructor
performance-noexcept-move-constructor
performance-noexcept-swap
performance-trivially-destructible
performance-type-promotion-in-math-fn
performance-unnecessary-copy-initialization
performance-unnecessary-value-param
portability-restrict-system-includes
portability-simd-intrinsics
portability-std-allocator-const
readability-avoid-unconditional-preprocessor-if
readability-const-return-type
readability-container-contains
readability-container-data-pointer
readability-container-size-empty
readability-convert-member-functions-to-static
readability-delete-null-pointer
readability-duplicate-include
readability-function-cognitive-complexity
readability-function-size
readability-inconsistent-declaration-parameter-name
readability-make-member-function-const
readability-misleading-indentation
readability-misplaced-array-index
readability-named-parameter
readability-non-const-parameter
readability-operators-representation
readability-qualified-auto
readability-redundant-access-specifiers
readability-redundant-control-flow
readability-redundant-declaration
readability-redundant-function-ptr-dereference
readability-redundant-member-init
readability-redundant-preprocessor
readability-redundant-smartptr-get
readability-redundant-string-cstr
readability-redundant-string-init
readability-simplify-boolean-expr
readability-simplify-subscript-expr
readability-static-definition-in-anonymous-namespace
readability-string-compare
readability-suspicious-call-argument
readability-uniqueptr-delete-release
readability-uppercase-literal-suffix
readability-use-anyofallof
zircon-temporary-objects
'
HeaderFilterRegex: \.h
AnalyzeTemporaryDtors: false
FormatStyle: none
CheckOptions:
- { key: readability-identifier-naming.NamespaceCase, value: lower_case }
# - { key: readability-identifier-naming.FunctionCase, value: lower_case }
- { key: readability-identifier-naming.ClassCase, value: CamelCase }
# - { key: readability-identifier-naming.MethodCase, value: CamelCase }
# - { key: readability-identifier-naming.StructCase, value: CamelCase }
# - { key: readability-identifier-naming.VariableCase, value: lower_case }
- { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE }
...

30
.github/workflows/clang-tidy.yml vendored Normal file
View File

@ -0,0 +1,30 @@
name: clang-tidy
on:
push:
jobs:
clang-tidy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: mamba-org/setup-micromamba@v1
if: ${{ contains(inputs.use-system-libraries, 'ON')}}
with:
micromamba-version: '1.5.6-0' # any version from https://github.com/mamba-org/micromamba-releases
environment-file: aare-environment.yml
init-shell: bash
cache-environment: true
post-cleanup: 'all'
- name: cmake
shell: bash -el {0}
run: |
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DUSE_SYSTEM_LIBRARIES=ON ..
- name: linting checks
shell: bash -el {0}
run: |
# find all examples in build/examples and run them
cd build
cmake --build . --target clang-tidy

View File

@ -19,7 +19,7 @@ jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: mamba-org/setup-micromamba@v1
if: ${{ contains(inputs.use-system-libraries, 'ON')}}
with:

View File

@ -6,14 +6,27 @@ jobs:
test-formatting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: check if files are formatted
# find all examples in build/examples and run them
- uses: actions/checkout@v4
- uses: mamba-org/setup-micromamba@v1
if: ${{ contains(inputs.use-system-libraries, 'ON')}}
with:
micromamba-version: '1.5.6-0' # any version from https://github.com/mamba-org/micromamba-releases
environment-file: aare-environment.yml
init-shell: bash
cache-environment: true
post-cleanup: 'all'
- name: cmake
shell: bash -el {0}
run: |
pwd
mkdir build
cd build
find \( -name "*.cpp" -o -name "*.hpp" \) -not -path "./build/*" | xargs -I {} -n 1 -P 10 bash -c "clang-format -i -style=\"file:.clang-format\" {}"
cmake -DCMAKE_BUILD_TYPE=Release -DUSE_SYSTEM_LIBRARIES=ON ..
- name: linting checks
shell: bash -el {0}
run: |
# find all examples in build/examples and run them
cd build
cmake --build . --target=check-format

View File

@ -206,3 +206,12 @@ add_custom_target(
COMMENT "Formatting with clang-format"
VERBATIM
)
add_custom_target(
clang-tidy
COMMAND find \( -path "./core/*" -o -path "./file_io/*" -path "./network_io/*" -path "./utils/*" \) \( -name "*.cpp" -o -name "*.hpp" \) -not -path "./python/*" -not -name "*.test.cpp" -not -name "CircularFifo.hpp" -not -name "ProducerConsumerQueue.hpp" -not -name "VariableSizeClusterFinder.hpp" | xargs -I {} -n 1 -P 10 bash -c "clang-tidy --config-file=.clang-tidy -p build {}"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "linting with clang-tidy"
VERBATIM
)

View File

@ -26,7 +26,7 @@ enum class endian {
*/
class DType {
// TODO! support for non native endianess?
static_assert(sizeof(long) == sizeof(int64_t), "long should be 64bits");
static_assert(sizeof(long) == sizeof(int64_t), "long should be 64bits"); // NOLINT
public:
enum TypeIndex { INT8, UINT8, INT16, UINT16, INT32, UINT32, INT64, UINT64, FLOAT, DOUBLE, ERROR };
@ -37,7 +37,7 @@ class DType {
explicit DType(std::string_view sv);
// not explicit to allow conversions form enum to DType
DType(DType::TypeIndex ti);
DType(DType::TypeIndex ti); // NOLINT
bool operator==(const DType &other) const noexcept;
bool operator!=(const DType &other) const noexcept;

View File

@ -4,7 +4,6 @@
#include <cstddef>
#include <cstdint>
#include <memory>
#include <sys/types.h>
#include <vector>
namespace aare {
@ -15,59 +14,73 @@ namespace aare {
* should be able to work with streams coming from files or network
*/
class Frame {
ssize_t m_rows;
ssize_t m_cols;
ssize_t m_bitdepth;
size_t m_rows;
size_t m_cols;
size_t m_bitdepth;
std::byte *m_data;
public:
Frame(ssize_t rows, ssize_t cols, ssize_t m_bitdepth);
Frame(std::byte *fp, ssize_t rows, ssize_t cols, ssize_t m_bitdepth);
std::byte *get(int row, int col);
Frame(size_t rows, size_t cols, size_t m_bitdepth);
Frame(std::byte *bytes, size_t rows, size_t cols, size_t m_bitdepth);
std::byte *get(size_t row, size_t col);
// TODO! can we, or even want to remove the template?
template <typename T> void set(int row, int col, T data) {
template <typename T> void set(size_t row, size_t col, T data) {
assert(sizeof(T) == m_bitdepth / 8);
if (row < 0 || row >= m_rows || col < 0 || col >= m_cols) {
if (row >= m_rows or col >= m_cols) {
throw std::out_of_range("Invalid row or column index");
}
std::memcpy(m_data + (row * m_cols + col) * (m_bitdepth / 8), &data, m_bitdepth / 8);
}
ssize_t rows() const { return m_rows; }
ssize_t cols() const { return m_cols; }
ssize_t bitdepth() const { return m_bitdepth; }
ssize_t size() const { return m_rows * m_cols * m_bitdepth / 8; }
size_t rows() const { return m_rows; }
size_t cols() const { return m_cols; }
size_t bitdepth() const { return m_bitdepth; }
size_t size() const { return m_rows * m_cols * m_bitdepth / 8; }
std::byte *data() const { return m_data; }
Frame &operator=(Frame &other) {
Frame &operator=(const Frame &other) {
if (this == &other) {
return *this;
}
m_rows = other.rows();
m_cols = other.cols();
m_bitdepth = other.bitdepth();
m_data = new std::byte[m_rows * m_cols * m_bitdepth / 8];
if (m_data == nullptr) {
throw std::bad_alloc();
}
std::memcpy(m_data, other.m_data, m_rows * m_cols * m_bitdepth / 8);
return *this;
}
// add move constructor
Frame(Frame &&other) {
Frame &operator=(Frame &&other) noexcept {
m_rows = other.rows();
m_cols = other.cols();
m_bitdepth = other.bitdepth();
m_data = other.m_data;
other.m_data = nullptr;
other.m_rows = other.m_cols = other.m_bitdepth = 0;
return *this;
}
// add move constructor
Frame(Frame &&other) noexcept
: m_rows(other.rows()), m_cols(other.cols()), m_bitdepth(other.bitdepth()), m_data(other.m_data) {
other.m_data = nullptr;
other.m_rows = other.m_cols = other.m_bitdepth = 0;
}
// copy constructor
Frame(const Frame &other) {
m_rows = other.rows();
m_cols = other.cols();
m_bitdepth = other.bitdepth();
m_data = new std::byte[m_rows * m_cols * m_bitdepth / 8];
Frame(const Frame &other)
: m_rows(other.rows()), m_cols(other.cols()), m_bitdepth(other.bitdepth()),
m_data(new std::byte[m_rows * m_cols * m_bitdepth / 8]) {
std::memcpy(m_data, other.m_data, m_rows * m_cols * m_bitdepth / 8);
}
template <typename T> NDView<T> view() {
std::vector<ssize_t> shape = {m_rows, m_cols};
std::vector<ssize_t> shape = {static_cast<ssize_t>(m_rows), static_cast<ssize_t>(m_cols)};
T *data = reinterpret_cast<T *>(m_data);
return NDView<T>(data, shape);
}

View File

@ -22,25 +22,25 @@ namespace aare {
template <typename T, ssize_t Ndim = 2> class NDArray {
public:
NDArray() : shape_(), strides_(c_strides<Ndim>(shape_)), size_(0), data_(nullptr){};
NDArray() : shape_(), strides_(c_strides<Ndim>(shape_)), data_(nullptr){};
explicit NDArray(std::array<ssize_t, Ndim> shape)
: shape_(shape), strides_(c_strides<Ndim>(shape_)),
size_(std::accumulate(shape_.begin(), shape_.end(), 1, std::multiplies<ssize_t>())), data_(new T[size_]){};
size_(std::accumulate(shape_.begin(), shape_.end(), 1, std::multiplies<>())), data_(new T[size_]){};
NDArray(std::array<ssize_t, Ndim> shape, T value) : NDArray(shape) { this->operator=(value); }
/* When constructing from a NDView we need to copy the data since
NDArray expect to own its data, and span is just a view*/
NDArray(NDView<T, Ndim> span) : NDArray(span.shape()) {
explicit NDArray(NDView<T, Ndim> span) : NDArray(span.shape()) {
std::copy(span.begin(), span.end(), begin());
// fmt::print("NDArray(NDView<T, Ndim> span)\n");
}
// Move constructor
NDArray(NDArray &&other)
: shape_(other.shape_), strides_(c_strides<Ndim>(shape_)), size_(other.size_), data_(nullptr) {
data_ = other.data_;
NDArray(NDArray &&other) noexcept
: shape_(other.shape_), strides_(c_strides<Ndim>(shape_)), size_(other.size_), data_(other.data_) {
other.reset();
// fmt::print("NDArray(NDArray &&other)\n");
}
@ -59,7 +59,7 @@ template <typename T, ssize_t Ndim = 2> class NDArray {
using value_type = T;
NDArray &operator=(NDArray &&other); // Move assign
NDArray &operator=(NDArray &&other) noexcept; // Move assign
NDArray &operator=(const NDArray &other); // Copy assign
NDArray operator+(const NDArray &other);
@ -77,9 +77,8 @@ template <typename T, ssize_t Ndim = 2> class NDArray {
data_[i] /= other(i);
}
return *this;
} else {
throw(std::runtime_error("Shape of NDArray must match"));
}
throw(std::runtime_error("Shape of NDArray must match"));
}
NDArray<bool, Ndim> operator>(const NDArray &other);
@ -87,17 +86,17 @@ template <typename T, ssize_t Ndim = 2> class NDArray {
bool operator==(const NDArray &other) const;
bool operator!=(const NDArray &other) const;
NDArray &operator=(const T &);
NDArray &operator+=(const T &);
NDArray operator+(const T &);
NDArray &operator-=(const T &);
NDArray operator-(const T &);
NDArray &operator*=(const T &);
NDArray operator*(const T &);
NDArray &operator/=(const T &);
NDArray operator/(const T &);
NDArray &operator=(const T & /*value*/);
NDArray &operator+=(const T & /*value*/);
NDArray operator+(const T & /*value*/);
NDArray &operator-=(const T & /*value*/);
NDArray operator-(const T & /*value*/);
NDArray &operator*=(const T & /*value*/);
NDArray operator*(const T & /*value*/);
NDArray &operator/=(const T & /*value*/);
NDArray operator/(const T & /*value*/);
NDArray &operator&=(const T &);
NDArray &operator&=(const T & /*mask*/);
void sqrt() {
for (int i = 0; i < size_; ++i) {
@ -107,15 +106,15 @@ template <typename T, ssize_t Ndim = 2> class NDArray {
NDArray &operator++(); // pre inc
template <typename... Ix> typename std::enable_if<sizeof...(Ix) == Ndim, T &>::type operator()(Ix... index) {
template <typename... Ix> std::enable_if_t<sizeof...(Ix) == Ndim, T &> operator()(Ix... index) {
return data_[element_offset(strides_, index...)];
}
template <typename... Ix> typename std::enable_if<sizeof...(Ix) == Ndim, T &>::type operator()(Ix... index) const {
template <typename... Ix> std::enable_if_t<sizeof...(Ix) == Ndim, T &> operator()(Ix... index) const {
return data_[element_offset(strides_, index...)];
}
template <typename... Ix> typename std::enable_if<sizeof...(Ix) == Ndim, T>::type value(Ix... index) {
template <typename... Ix> std::enable_if_t<sizeof...(Ix) == Ndim, T> value(Ix... index) {
return data_[element_offset(strides_, index...)];
}
@ -153,12 +152,12 @@ template <typename T, ssize_t Ndim = 2> class NDArray {
private:
std::array<ssize_t, Ndim> shape_;
std::array<ssize_t, Ndim> strides_;
ssize_t size_;
ssize_t size_{};
T *data_;
};
// Move assign
template <typename T, ssize_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator=(NDArray<T, Ndim> &&other) {
template <typename T, ssize_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator=(NDArray<T, Ndim> &&other) noexcept {
if (this != &other) {
delete[] data_;
data_ = other.data_;
@ -182,9 +181,8 @@ template <typename T, ssize_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator
data_[i] += other.data_[i];
}
return *this;
} else {
throw(std::runtime_error("Shape of ImageDatas must match"));
}
throw(std::runtime_error("Shape of ImageDatas must match"));
}
template <typename T, ssize_t Ndim> NDArray<T, Ndim> NDArray<T, Ndim>::operator-(const NDArray &other) {
@ -200,9 +198,8 @@ template <typename T, ssize_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator
data_[i] -= other.data_[i];
}
return *this;
} else {
throw(std::runtime_error("Shape of ImageDatas must match"));
}
throw(std::runtime_error("Shape of ImageDatas must match"));
}
template <typename T, ssize_t Ndim> NDArray<T, Ndim> NDArray<T, Ndim>::operator*(const NDArray &other) {
NDArray result = *this;
@ -217,9 +214,8 @@ template <typename T, ssize_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator
data_[i] *= other.data_[i];
}
return *this;
} else {
throw(std::runtime_error("Shape of ImageDatas must match"));
}
throw(std::runtime_error("Shape of ImageDatas must match"));
}
template <typename T, ssize_t Ndim> NDArray<T, Ndim> NDArray<T, Ndim>::operator/(const NDArray &other) {
@ -256,9 +252,8 @@ template <typename T, ssize_t Ndim> NDArray<bool, Ndim> NDArray<T, Ndim>::operat
result(i) = (data_[i] > other.data_[i]);
}
return result;
} else {
throw(std::runtime_error("Shape of ImageDatas must match"));
}
throw(std::runtime_error("Shape of ImageDatas must match"));
}
template <typename T, ssize_t Ndim> NDArray<T, Ndim> &NDArray<T, Ndim>::operator=(const NDArray<T, Ndim> &other) {
@ -364,7 +359,7 @@ template <typename T, ssize_t Ndim> void NDArray<T, Ndim>::Print_some() {
}
}
template <typename T, ssize_t Ndim> void save(NDArray<T, Ndim> &img, std::string pathname) {
template <typename T, ssize_t Ndim> void save(NDArray<T, Ndim> &img, std::string &pathname) {
std::ofstream f;
f.open(pathname, std::ios::binary);
f.write(img.buffer(), img.size() * sizeof(T));

View File

@ -20,7 +20,7 @@ template <ssize_t Ndim> Shape<Ndim> make_shape(const std::vector<size_t> &shape)
return arr;
}
template <ssize_t Dim = 0, typename Strides> ssize_t element_offset(const Strides &) { return 0; }
template <ssize_t Dim = 0, typename Strides> ssize_t element_offset(const Strides & /*unused*/) { return 0; }
template <ssize_t Dim = 0, typename Strides, typename... Ix>
ssize_t element_offset(const Strides &strides, ssize_t i, Ix... index) {
@ -28,7 +28,7 @@ ssize_t element_offset(const Strides &strides, ssize_t i, Ix... index) {
}
template <ssize_t Ndim> std::array<ssize_t, Ndim> c_strides(const std::array<ssize_t, Ndim> &shape) {
std::array<ssize_t, Ndim> strides;
std::array<ssize_t, Ndim> strides{};
std::fill(strides.begin(), strides.end(), 1);
for (ssize_t i = Ndim - 1; i > 0; --i) {
strides[i - 1] = strides[i] * shape[i];
@ -38,42 +38,36 @@ template <ssize_t Ndim> std::array<ssize_t, Ndim> c_strides(const std::array<ssi
template <ssize_t Ndim> std::array<ssize_t, Ndim> make_array(const std::vector<ssize_t> &vec) {
assert(vec.size() == Ndim);
std::array<ssize_t, Ndim> arr;
std::array<ssize_t, Ndim> arr{};
std::copy_n(vec.begin(), Ndim, arr.begin());
return arr;
}
template <typename T, ssize_t Ndim = 2> class NDView {
public:
NDView(){};
NDView() = default;
~NDView() = default;
NDView(const NDView &) = default;
NDView(NDView &&) = default;
NDView(T *buffer, std::array<ssize_t, Ndim> shape) {
buffer_ = buffer;
strides_ = c_strides<Ndim>(shape);
shape_ = shape;
size_ = std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<ssize_t>());
}
NDView(T *buffer, std::array<ssize_t, Ndim> shape)
: buffer_(buffer), strides_(c_strides<Ndim>(shape)), shape_(shape),
size_(std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<>())) {}
NDView(T *buffer, const std::vector<ssize_t> &shape) {
buffer_ = buffer;
strides_ = c_strides<Ndim>(make_array<Ndim>(shape));
shape_ = make_array<Ndim>(shape);
size_ = std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<ssize_t>());
}
NDView(T *buffer, const std::vector<ssize_t> &shape)
: buffer_(buffer), strides_(c_strides<Ndim>(make_array<Ndim>(shape))), shape_(make_array<Ndim>(shape)),
size_(std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<>())) {}
template <typename... Ix> typename std::enable_if<sizeof...(Ix) == Ndim, T &>::type operator()(Ix... index) {
template <typename... Ix> std::enable_if_t<sizeof...(Ix) == Ndim, T &> operator()(Ix... index) {
return buffer_[element_offset(strides_, index...)];
}
template <typename... Ix> typename std::enable_if<sizeof...(Ix) == Ndim, T &>::type operator()(Ix... index) const {
template <typename... Ix> std::enable_if_t<sizeof...(Ix) == Ndim, T &> operator()(Ix... index) const {
return buffer_[element_offset(strides_, index...)];
}
ssize_t size() const { return size_; }
NDView(const NDView &) = default;
NDView(NDView &&) = default;
T *begin() { return buffer_; }
T *end() { return buffer_ + size_; }
T &operator()(ssize_t i) { return buffer_[i]; }
@ -103,12 +97,26 @@ template <typename T, ssize_t Ndim = 2> class NDView {
}
NDView &operator=(const NDView &other) {
if (this == &other)
return *this;
shape_ = other.shape_;
strides_ = other.strides_;
size_ = other.size_;
buffer_ = other.buffer_;
return *this;
}
NDView &operator=(NDView &&other) noexcept {
if (this == &other)
return *this;
shape_ = std::move(other.shape_);
strides_ = std::move(other.strides_);
size_ = other.size_;
buffer_ = other.buffer_;
other.buffer_ = nullptr;
return *this;
}
auto &shape() { return shape_; }
auto shape(ssize_t i) const { return shape_[i]; }

View File

@ -28,7 +28,7 @@ struct sls_detector_header {
uint16_t roundRNumber;
uint8_t detType;
uint8_t version;
uint8_t packetMask[64];
std::array<uint8_t, 64> packetMask;
};
struct xy {
@ -44,14 +44,14 @@ enum class DetectorType { Jungfrau, Eiger, Mythen3, Moench, ChipTestBoard };
enum class TimingMode { Auto, Trigger };
template <class T> T StringTo(std::string sv) { return T(sv); }
template <class T> T StringTo(const std::string &arg) { return T(arg); }
template <class T> std::string toString(T sv) { return T(sv); }
template <class T> std::string toString(T arg) { return T(arg); }
template <> DetectorType StringTo(std::string);
template <> std::string toString(DetectorType type);
template <> DetectorType StringTo(const std::string & /*name*/);
template <> std::string toString(DetectorType arg);
template <> TimingMode StringTo(std::string);
template <> TimingMode StringTo(const std::string & /*mode*/);
using DataTypeVariants = std::variant<uint16_t, uint32_t>;

View File

@ -1,8 +1,7 @@
#include "aare/core/DType.hpp"
#include "aare/utils/logger.hpp"
#include <fmt/format.h>
#include <fmt/core.h>
namespace aare {
@ -26,9 +25,7 @@ DType::DType(const std::type_info &t) {
m_type = TypeIndex::INT32;
else if (t == typeid(uint32_t))
m_type = TypeIndex::UINT32;
else if (t == typeid(int64_t))
m_type = TypeIndex::INT64;
else if (t == typeid(long))
else if (t == typeid(int64_t) || t == typeid(long)) // NOLINT
m_type = TypeIndex::INT64;
else if (t == typeid(uint64_t))
m_type = TypeIndex::UINT64;
@ -130,7 +127,7 @@ DType::DType(std::string_view sv) {
*/
std::string DType::str() const {
char ec;
char ec{};
if (endian::native == endian::little)
ec = '<';
else

View File

@ -1,7 +1,8 @@
#include "aare/core/Frame.hpp"
#include "aare/utils/logger.hpp"
#include <cassert>
#include <cstddef>
#include <cstring>
#include <iostream>
#include <sys/types.h>
namespace aare {
@ -12,9 +13,9 @@ namespace aare {
* @param cols number of columns
* @param bitdepth bitdepth of the pixels
*/
Frame::Frame(std::byte *bytes, ssize_t rows, ssize_t cols, ssize_t bitdepth)
: m_rows(rows), m_cols(cols), m_bitdepth(bitdepth) {
m_data = new std::byte[rows * cols * bitdepth / 8];
Frame::Frame(std::byte *bytes, size_t rows, size_t cols, size_t bitdepth)
: m_rows(rows), m_cols(cols), m_bitdepth(bitdepth), m_data(new std::byte[rows * cols * bitdepth / 8]) {
std::memcpy(m_data, bytes, rows * cols * bitdepth / 8);
}
@ -25,8 +26,9 @@ Frame::Frame(std::byte *bytes, ssize_t rows, ssize_t cols, ssize_t bitdepth)
* @param bitdepth bitdepth of the pixels
* @note the data is initialized to zero
*/
Frame::Frame(ssize_t rows, ssize_t cols, ssize_t bitdepth) : m_rows(rows), m_cols(cols), m_bitdepth(bitdepth) {
m_data = new std::byte[rows * cols * bitdepth / 8];
Frame::Frame(size_t rows, size_t cols, size_t bitdepth)
: m_rows(rows), m_cols(cols), m_bitdepth(bitdepth), m_data(new std::byte[rows * cols * bitdepth / 8]) {
std::memset(m_data, 0, rows * cols * bitdepth / 8);
}
@ -37,10 +39,10 @@ Frame::Frame(ssize_t rows, ssize_t cols, ssize_t bitdepth) : m_rows(rows), m_col
* @return pointer to the pixel
* @note the user should cast the pointer to the appropriate type
*/
std::byte *Frame::get(int row, int col) {
if (row < 0 || row >= m_rows || col < 0 || col >= m_cols) {
std::cerr << "Invalid row or column index" << std::endl;
return 0;
std::byte *Frame::get(size_t row, size_t col) {
if (row >= m_rows or col >= m_cols) {
std::cerr << "Invalid row or column index" << '\n';
return nullptr;
}
return m_data + (row * m_cols + col) * (m_bitdepth / 8);
}

View File

@ -1,4 +1,6 @@
#include "aare/core/defs.hpp"
#include <stdexcept>
#include <string>
namespace aare {
@ -7,8 +9,8 @@ namespace aare {
* @param type DetectorType
* @return string representation of the DetectorType
*/
template <> std::string toString(DetectorType type) {
switch (type) {
template <> std::string toString(DetectorType arg) {
switch (arg) {
case DetectorType::Jungfrau:
return "Jungfrau";
case DetectorType::Eiger:
@ -30,20 +32,18 @@ template <> std::string toString(DetectorType type) {
* @return DetectorType
* @throw runtime_error if the string does not match any DetectorType
*/
template <> DetectorType StringTo(std::string name) {
if (name == "Jungfrau")
template <> DetectorType StringTo(const std::string &arg) {
if (arg == "Jungfrau")
return DetectorType::Jungfrau;
else if (name == "Eiger")
if (arg == "Eiger")
return DetectorType::Eiger;
else if (name == "Mythen3")
if (arg == "Mythen3")
return DetectorType::Mythen3;
else if (name == "Moench")
if (arg == "Moench")
return DetectorType::Moench;
else if (name == "ChipTestBoard")
if (arg == "ChipTestBoard")
return DetectorType::ChipTestBoard;
else {
throw std::runtime_error("Could not decode dector from: \"" + name + "\"");
}
throw std::runtime_error("Could not decode dector from: \"" + arg + "\"");
}
/**
@ -52,14 +52,12 @@ template <> DetectorType StringTo(std::string name) {
* @return TimingMode
* @throw runtime_error if the string does not match any TimingMode
*/
template <> TimingMode StringTo(std::string mode) {
if (mode == "auto")
template <> TimingMode StringTo(const std::string &arg) {
if (arg == "auto")
return TimingMode::Auto;
else if (mode == "trigger")
if (arg == "trigger")
return TimingMode::Trigger;
else {
throw std::runtime_error("Could not decode timing mode from: \"" + mode + "\"");
}
throw std::runtime_error("Could not decode timing mode from: \"" + arg + "\"");
}
// template <> TimingMode StringTo<TimingMode>(std::string mode);

View File

@ -4,9 +4,9 @@
using aare::Frame;
TEST_CASE("Construct a frame") {
ssize_t rows = 10;
ssize_t cols = 10;
ssize_t bitdepth = 8;
size_t rows = 10;
size_t cols = 10;
size_t bitdepth = 8;
Frame frame(rows, cols, bitdepth);
@ -16,8 +16,8 @@ TEST_CASE("Construct a frame") {
REQUIRE(frame.size() == rows * cols * bitdepth / 8);
// data should be initialized to 0
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < cols; j++) {
uint8_t *data = (uint8_t *)frame.get(i, j);
REQUIRE(data != nullptr);
REQUIRE(*data == 0);
@ -26,9 +26,9 @@ TEST_CASE("Construct a frame") {
}
TEST_CASE("Set a value in a 8 bit frame") {
ssize_t rows = 10;
ssize_t cols = 10;
ssize_t bitdepth = 8;
size_t rows = 10;
size_t cols = 10;
size_t bitdepth = 8;
Frame frame(rows, cols, bitdepth);
@ -37,8 +37,8 @@ TEST_CASE("Set a value in a 8 bit frame") {
frame.set(5, 7, value);
// only the value we did set should be non-zero
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < cols; j++) {
uint8_t *data = (uint8_t *)frame.get(i, j);
REQUIRE(data != nullptr);
if (i == 5 && j == 7) {
@ -51,9 +51,9 @@ TEST_CASE("Set a value in a 8 bit frame") {
}
TEST_CASE("Set a value in a 64 bit frame") {
ssize_t rows = 10;
ssize_t cols = 10;
ssize_t bitdepth = 64;
size_t rows = 10;
size_t cols = 10;
size_t bitdepth = 64;
Frame frame(rows, cols, bitdepth);
@ -62,8 +62,8 @@ TEST_CASE("Set a value in a 64 bit frame") {
frame.set(5, 7, value);
// only the value we did set should be non-zero
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < cols; j++) {
uint64_t *data = (uint64_t *)frame.get(i, j);
REQUIRE(data != nullptr);
if (i == 5 && j == 7) {
@ -76,9 +76,9 @@ TEST_CASE("Set a value in a 64 bit frame") {
}
TEST_CASE("Move construct a frame") {
ssize_t rows = 10;
ssize_t cols = 10;
ssize_t bitdepth = 8;
size_t rows = 10;
size_t cols = 10;
size_t bitdepth = 8;
Frame frame(rows, cols, bitdepth);
std::byte *data = frame.data();

View File

@ -9,18 +9,18 @@ using aare::File;
using aare::Frame;
void test(File &f, int frame_number) {
std::cout << "frame number: " << frame_number << std::endl;
std::cout << "frame number: " << frame_number << '\n';
Frame frame = f.iread(frame_number);
std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl;
std::cout << *((uint16_t *)frame.get(0, 1)) << std::endl;
std::cout << *((uint16_t *)frame.get(1, 0)) << std::endl;
std::cout << *((uint16_t *)frame.get(511, 1023)) << std::endl;
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 0))) << '\n';
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 1))) << '\n';
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(1, 0))) << '\n';
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(511, 1023))) << '\n';
}
int main() {
auto PROJECT_ROOT_DIR = std::filesystem::path(getenv(AARE_ROOT_DIR_VAR));
std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "jungfrau" / "jungfrau_single_master_0.json");
std::cout << fpath << std::endl;
std::filesystem::path const fpath(PROJECT_ROOT_DIR / "data" / "jungfrau" / "jungfrau_single_master_0.json");
std::cout << fpath << '\n';
File file(fpath, "r");
test(file, 0);

View File

@ -9,19 +9,19 @@ using aare::File;
using aare::Frame;
void test(File &f, int frame_number) {
std::cout << "frame number: " << frame_number << std::endl;
std::cout << "frame number: " << frame_number << '\n';
Frame frame = f.iread(frame_number);
std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl;
std::cout << *((uint16_t *)frame.get(0, 1)) << std::endl;
std::cout << *((uint16_t *)frame.get(0, 1)) << std::endl;
std::cout << *((uint16_t *)frame.get(255, 1023)) << std::endl;
std::cout << *((uint16_t *)frame.get(511, 1023)) << std::endl;
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 0))) << '\n';
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 1))) << '\n';
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 1))) << '\n';
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(255, 1023))) << '\n';
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(511, 1023))) << '\n';
}
int main() {
auto PROJECT_ROOT_DIR = std::filesystem::path(getenv(AARE_ROOT_DIR_VAR));
std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "jungfrau" / "jungfrau_double_master_0.json");
std::cout << fpath << std::endl;
std::filesystem::path const fpath(PROJECT_ROOT_DIR / "data" / "jungfrau" / "jungfrau_double_master_0.json");
std::cout << fpath << '\n';
File file(fpath, "r");
test(file, 0);

View File

@ -9,14 +9,14 @@ using aare::File;
using aare::Frame;
void test1(File &f, int frame_number) {
std::cout << "frame number: " << frame_number << std::endl;
std::cout << "frame number: " << frame_number << '\n';
Frame frame = f.iread(frame_number);
std::cout << *((uint32_t *)frame.get(0, 0)) << std::endl;
std::cout << *((uint32_t *)frame.get(0, 1)) << std::endl;
std::cout << *((uint32_t *)frame.get(0, 3839)) << std::endl;
std::cout << *(reinterpret_cast<uint32_t *>(frame.get(0, 0))) << '\n';
std::cout << *(reinterpret_cast<uint32_t *>(frame.get(0, 1))) << '\n';
std::cout << *(reinterpret_cast<uint32_t *>(frame.get(0, 3839))) << '\n';
for (int i = 0; i < 3840; i++) {
uint16_t x = *((uint32_t *)frame.get(0, i));
uint16_t const x = *(reinterpret_cast<uint32_t *>(frame.get(0, i)));
if (x != i) {
aare::logger::error("error at i", i, "x", x);
}
@ -24,11 +24,11 @@ void test1(File &f, int frame_number) {
}
void test2(File &f, int frame_number) {
std::cout << "frame number: " << frame_number << std::endl;
std::cout << "frame number: " << frame_number << '\n';
Frame frame = f.iread(frame_number);
std::cout << *((uint32_t *)frame.get(0, 0)) << std::endl;
std::cout << *((uint32_t *)frame.get(0, 1)) << std::endl;
std::cout << *((uint32_t *)frame.get(0, 1280 * 4 - 1)) << std::endl;
std::cout << *(reinterpret_cast<uint32_t *>(frame.get(0, 0))) << '\n';
std::cout << *(reinterpret_cast<uint32_t *>(frame.get(0, 1))) << '\n';
std::cout << *(reinterpret_cast<uint32_t *>(frame.get(0, 1280 * 4 - 1))) << '\n';
}
int main() {

View File

@ -8,19 +8,19 @@ using aare::File;
using aare::Frame;
void test(File &f, int frame_number) {
std::cout << "frame number: " << frame_number << std::endl;
std::cout << "frame number: " << frame_number << '\n';
Frame frame = f.iread(frame_number);
std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl;
std::cout << *((uint16_t *)frame.get(0, 1)) << std::endl;
std::cout << *((uint16_t *)frame.get(1, 0)) << std::endl;
std::cout << *((uint16_t *)frame.get(49, 49)) << std::endl;
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 0))) << '\n';
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 1))) << '\n';
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(1, 0))) << '\n';
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(49, 49))) << '\n';
}
int main() {
auto PROJECT_ROOT_DIR = std::filesystem::path(getenv(AARE_ROOT_DIR_VAR));
std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "numpy" / "test_numpy_file.npy");
std::cout << fpath << std::endl;
std::filesystem::path const fpath(PROJECT_ROOT_DIR / "data" / "numpy" / "test_numpy_file.npy");
std::cout << fpath << '\n';
File file(fpath, "r");
test(file, 0);

View File

@ -12,7 +12,7 @@ using aare::Frame;
int main() {
auto path = std::filesystem::path("/tmp/test.npy");
auto dtype = aare::DType(typeid(uint32_t));
FileConfig cfg = {dtype, 100, 100};
FileConfig const cfg = {dtype, 100, 100};
File npy(path, "w", cfg);
Frame f(100, 100, dtype.bitdepth());
for (int i = 0; i < 10000; i++) {

View File

@ -9,11 +9,11 @@ using aare::File;
using aare::Frame;
void test(File &f, int frame_number) {
std::cout << "frame number: " << frame_number << std::endl;
std::cout << "frame number: " << frame_number << '\n';
Frame frame = f.iread(frame_number);
std::cout << *((uint16_t *)frame.get(0, 0)) << std::endl;
std::cout << *((uint16_t *)frame.get(0, 1)) << std::endl;
std::cout << *((uint16_t *)frame.get(0, 95)) << std::endl;
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 0))) << '\n';
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 1))) << '\n';
std::cout << *(reinterpret_cast<uint16_t *>(frame.get(0, 95))) << '\n';
}
int main() {
@ -21,7 +21,7 @@ int main() {
if (PROJECT_ROOT_DIR.empty()) {
throw std::runtime_error("environment variable PROJECT_ROOT_DIR is not set");
}
std::filesystem::path fpath(PROJECT_ROOT_DIR / "data" / "moench" /
std::filesystem::path const fpath(PROJECT_ROOT_DIR / "data" / "moench" /
"moench04_noise_200V_sto_both_100us_no_light_thresh_900_master_0.raw");
File file(fpath, "r");
test(file, 0);

View File

@ -35,7 +35,7 @@ int main(int argc, char **argv) {
auto port = vm["port"].as<uint16_t>();
std::string endpoint = "udp://127.0.0.1:" + std::to_string(port);
std::string const endpoint = "udp://127.0.0.1:" + std::to_string(port);
aare::ZmqSocketReceiver socket(endpoint);
socket.connect();
while (true) {

View File

@ -48,10 +48,10 @@ int main(int argc, char **argv) {
return 1;
}
std::string path = vm["file"].as<string>();
uint16_t port = vm["port"].as<uint16_t>();
bool loop = vm.count("loop") == 1 ? true : false;
uint16_t fps = vm["fps"].as<uint16_t>();
std::string const path = vm["file"].as<string>();
uint16_t const port = vm["port"].as<uint16_t>();
bool const loop = vm.count("loop") == 1;
uint16_t const fps = vm["fps"].as<uint16_t>();
aare::logger::debug("ARGS: file:", path, "port:", port, "fps:", fps, "loop:", loop);
auto d = round<std::chrono::milliseconds>(std::chrono::duration<double>{1. / fps});
@ -62,17 +62,17 @@ int main(int argc, char **argv) {
return 1;
}
std::filesystem::path tmp(path);
std::filesystem::path const tmp(path);
File file(tmp, "r");
string endpoint = "tcp://*:" + std::to_string(port);
string const endpoint = "tcp://*:" + std::to_string(port);
ZmqSocketSender sender(endpoint);
sender.bind();
std::this_thread::sleep_for(d); // slow joiner problem should fix this
for (size_t frameidx = 0; frameidx < file.total_frames(); frameidx++) {
Frame frame = file.read();
Frame const frame = file.read();
ZmqHeader header;
header.frameNumber = frameidx;
header.data = true;

View File

@ -12,7 +12,7 @@ using namespace aare;
int main() {
std::srand(std::time(nullptr));
std::string endpoint = "tcp://*:5555";
std::string const endpoint = "tcp://*:5555";
aare::ZmqSocketSender socket(endpoint);
socket.bind();
Frame frame(1024, 1024, sizeof(uint32_t) * 8);
@ -34,7 +34,7 @@ int main() {
while (true) {
zmq_frames.clear();
header.acqIndex = acqid++;
size_t n_frames = std::rand() % 10 + 1;
size_t const n_frames = std::rand() % 10 + 1;
aare::logger::info("acquisition:", header.acqIndex);
aare::logger::info("Header size:", header.to_string().size());
@ -44,7 +44,7 @@ int main() {
for (size_t i = 0; i < n_frames; i++) {
zmq_frames.push_back({header, frame});
}
size_t rc = socket.send(zmq_frames);
size_t const rc = socket.send(zmq_frames);
aare::logger::info("Sent bytes", rc);
sleep(1);
}

View File

@ -22,7 +22,7 @@ class File {
* @throws std::invalid_argument if the file mode is not supported
*
*/
File(std::filesystem::path fname, std::string mode, FileConfig cfg = {});
File(const std::filesystem::path &fname, const std::string &mode, FileConfig cfg = {});
void write(Frame &frame);
Frame read();
Frame iread(size_t frame_number);
@ -31,19 +31,19 @@ class File {
void read_into(std::byte *image_buf, size_t n_frames);
size_t frame_number(size_t frame_index);
size_t bytes_per_frame();
size_t pixels();
size_t pixels_per_frame();
void seek(size_t frame_number);
size_t tell() const;
size_t total_frames() const;
ssize_t rows() const;
ssize_t cols() const;
ssize_t bitdepth() const;
size_t rows() const;
size_t cols() const;
size_t bitdepth() const;
/**
* @brief Move constructor
* @param other File object to move from
*/
File(File &&other);
File(File &&other) noexcept;
/**
* @brief destructor: will only delete the FileInterface object

View File

@ -16,8 +16,8 @@ namespace aare {
*/
struct FileConfig {
aare::DType dtype = aare::DType(typeid(uint16_t));
uint64_t rows;
uint64_t cols;
uint64_t rows{};
uint64_t cols{};
xy geometry{1, 1};
bool operator==(const FileConfig &other) const {
return dtype == other.dtype && rows == other.rows && cols == other.cols && geometry == other.geometry;
@ -92,7 +92,7 @@ class FileInterface {
* @brief get the number of pixels in one frame
* @return number of pixels in one frame
*/
virtual size_t pixels() = 0;
virtual size_t pixels_per_frame() = 0;
/**
* @brief seek to the given frame number
@ -116,17 +116,17 @@ class FileInterface {
* @brief get the number of rows in the file
* @return number of rows in the file
*/
virtual ssize_t rows() const = 0;
virtual size_t rows() const = 0;
/**
* @brief get the number of columns in the file
* @return number of columns in the file
*/
virtual ssize_t cols() const = 0;
virtual size_t cols() const = 0;
/**
* @brief get the bitdepth of the file
* @return bitdepth of the file
*/
virtual ssize_t bitdepth() const = 0;
virtual size_t bitdepth() const = 0;
/**
* @brief read one frame from the file at the given frame number
@ -158,23 +158,21 @@ class FileInterface {
// function to query the data type of the file
/*virtual DataType dtype = 0; */
virtual ~FileInterface(){
};
virtual ~FileInterface() = default;
protected:
std::string m_mode;
std::filesystem::path m_fname;
std::filesystem::path m_base_path;
std::string m_base_name, m_ext;
int m_findex;
std::string m_mode{};
std::filesystem::path m_fname{};
std::filesystem::path m_base_path{};
std::string m_base_name{}, m_ext{};
int m_findex{};
size_t m_total_frames{};
size_t max_frames_per_file{};
std::string version;
DetectorType m_type;
ssize_t m_rows{};
ssize_t m_cols{};
ssize_t m_bitdepth{};
std::string version{};
DetectorType m_type{};
size_t m_rows{};
size_t m_cols{};
size_t m_bitdepth{};
size_t current_frame{};
};

View File

@ -3,6 +3,7 @@
#include "aare/core/defs.hpp"
#include "aare/file_io/FileInterface.hpp"
#include "aare/file_io/NumpyHelpers.hpp"
#include "aare/utils/logger.hpp"
#include <filesystem>
#include <iostream>
#include <numeric>
@ -24,7 +25,7 @@ class NumpyFile : public FileInterface {
* @param mode file mode (r, w)
* @param cfg file configuration
*/
NumpyFile(const std::filesystem::path &fname, const std::string &mode = "r", FileConfig cfg = {});
explicit NumpyFile(const std::filesystem::path &fname, const std::string &mode = "r", FileConfig cfg = {});
void write(Frame &frame) override;
Frame read() override { return get_frame(this->current_frame++); }
@ -34,13 +35,13 @@ class NumpyFile : public FileInterface {
void read_into(std::byte *image_buf, size_t n_frames) override;
size_t frame_number(size_t frame_index) override { return frame_index; };
size_t bytes_per_frame() override;
size_t pixels() override;
size_t pixels_per_frame() override;
void seek(size_t frame_number) override { this->current_frame = frame_number; }
size_t tell() override { return this->current_frame; }
size_t total_frames() const override { return m_header.shape[0]; }
ssize_t rows() const override { return m_header.shape[1]; }
ssize_t cols() const override { return m_header.shape[2]; }
ssize_t bitdepth() const override { return m_header.dtype.bitdepth(); }
size_t rows() const override { return m_header.shape[1]; }
size_t cols() const override { return m_header.shape[2]; }
size_t bitdepth() const override { return m_header.dtype.bitdepth(); }
/**
* @brief get the data type of the numpy file
@ -62,12 +63,17 @@ class NumpyFile : public FileInterface {
*/
template <typename T, size_t NDim> NDArray<T, NDim> load() {
NDArray<T, NDim> arr(make_shape<NDim>(m_header.shape));
fseek(fp, header_size, SEEK_SET);
fread(arr.data(), sizeof(T), arr.size(), fp);
if (fseek(fp, static_cast<int64_t>(header_size), SEEK_SET)) {
throw std::runtime_error(LOCATION + "Error seeking to the start of the data");
}
size_t rc = fread(arr.data(), sizeof(T), arr.size(), fp);
if (rc != static_cast<size_t>(arr.size())) {
throw std::runtime_error(LOCATION + "Error reading data from file");
}
return arr;
}
~NumpyFile();
~NumpyFile() noexcept override;
private:
FILE *fp = nullptr;
@ -79,9 +85,11 @@ class NumpyFile : public FileInterface {
NumpyHeader m_header;
uint8_t major_ver_{};
uint8_t minor_ver_{};
size_t m_bytes_per_frame{};
size_t m_pixels_per_frame{};
void load_metadata();
void get_frame_into(size_t, std::byte *);
void get_frame_into(size_t /*frame_number*/, std::byte * /*image_buf*/);
Frame get_frame(size_t frame_number);
};

View File

@ -51,7 +51,7 @@ template <typename T, size_t N> bool in_array(T val, const std::array<T, N> &arr
bool is_digits(const std::string &str);
aare::DType parse_descr(std::string typestring);
size_t write_header(std::filesystem::path fname, const NumpyHeader &header);
size_t write_header(const std::filesystem::path &fname, const NumpyHeader &header);
size_t write_header(std::ostream &out, const NumpyHeader &header);
} // namespace NumpyHelpers

View File

@ -18,13 +18,13 @@ class RawFile : public FileInterface {
* @param mode file mode (r, w)
* @param cfg file configuration
*/
RawFile(const std::filesystem::path &fname, const std::string &mode = "r", const FileConfig &cfg = {});
explicit RawFile(const std::filesystem::path &fname, const std::string &mode = "r", const FileConfig &config = {});
/**
* @brief write function is not implemented for RawFile
* @param frame frame to write
*/
void write(Frame &frame) override { throw std::runtime_error("Not implemented"); };
void write(Frame & /*frame*/) override { throw std::runtime_error("Not implemented"); };
Frame read() override { return get_frame(this->current_frame++); };
std::vector<Frame> read(size_t n_frames) override;
void read_into(std::byte *image_buf) override { return get_frame_into(this->current_frame++, image_buf); };
@ -41,7 +41,7 @@ class RawFile : public FileInterface {
* @brief get the number of pixels in the frame
* @return number of pixels
*/
size_t pixels() override { return m_rows * m_cols; }
size_t pixels_per_frame() override { return m_rows * m_cols; }
// goto frame number
void seek(size_t frame_number) override { this->current_frame = frame_number; };
@ -53,7 +53,7 @@ class RawFile : public FileInterface {
* @brief check if the file is a master file
* @param fpath path to the file
*/
static bool is_master_file(std::filesystem::path fpath);
static bool is_master_file(const std::filesystem::path &fpath);
/**
* @brief set the module gap row and column
@ -83,17 +83,17 @@ class RawFile : public FileInterface {
* @param file_id file id
* @return path to the data file
*/
inline std::filesystem::path data_fname(int mod_id, int file_id);
inline std::filesystem::path data_fname(size_t mod_id, size_t file_id);
/**
* @brief destructor: will delete the subfiles
*/
~RawFile();
~RawFile() override;
size_t total_frames() const override { return m_total_frames; }
ssize_t rows() const override { return m_rows; }
ssize_t cols() const override { return m_cols; }
ssize_t bitdepth() const override { return m_bitdepth; }
size_t rows() const override { return m_rows; }
size_t cols() const override { return m_cols; }
size_t bitdepth() const override { return m_bitdepth; }
private:
/**
@ -101,7 +101,7 @@ class RawFile : public FileInterface {
* @param frame_number frame number to read
* @param image_buf buffer to store the frame
*/
void get_frame_into(size_t frame_number, std::byte *image_buf);
void get_frame_into(size_t frame_number, std::byte *frame_buffer);
/**
* @brief get the frame at the given frame number
@ -140,22 +140,21 @@ class RawFile : public FileInterface {
* @param fname path to the data subfile
* @return sls_detector_header
*/
sls_detector_header read_header(const std::filesystem::path &fname);
static sls_detector_header read_header(const std::filesystem::path &fname);
/**
* @brief open the subfiles
*/
void open_subfiles();
private:
size_t n_subfiles;
size_t n_subfile_parts;
size_t n_subfiles{};
size_t n_subfile_parts{};
std::vector<std::vector<SubFile *>> subfiles;
int subfile_rows, subfile_cols;
xy geometry;
size_t subfile_rows{}, subfile_cols{};
xy geometry{};
std::vector<xy> positions;
RawFileConfig cfg{0, 0};
TimingMode timing_mode;
TimingMode timing_mode{};
bool quad{false};
};

View File

@ -45,7 +45,7 @@ class SubFile {
* @param bitdepth bitdepth of the subfile
* @throws std::invalid_argument if the detector,type pair is not supported
*/
SubFile(std::filesystem::path fname, DetectorType detector, ssize_t rows, ssize_t cols, uint16_t bitdepth);
SubFile(const std::filesystem::path &fname, DetectorType detector, size_t rows, size_t cols, size_t bitdepth);
/**
* @brief read the subfile into a buffer
@ -74,20 +74,20 @@ class SubFile {
* @param frame_number frame number to read
* @return number of bytes read
*/
size_t get_part(std::byte *buffer, int frame_number);
size_t frame_number(int frame_index);
size_t get_part(std::byte *buffer, size_t frame_number);
size_t frame_number(size_t frame_index);
// TODO: define the inlines as variables and assign them in constructor
inline size_t bytes_per_part() { return (m_bitdepth / 8) * m_rows * m_cols; }
inline size_t pixels_per_part() { return m_rows * m_cols; }
inline size_t bytes_per_part() const { return (m_bitdepth / 8) * m_rows * m_cols; }
inline size_t pixels_per_part() const { return m_rows * m_cols; }
protected:
FILE *fp = nullptr;
ssize_t m_bitdepth;
size_t m_bitdepth;
std::filesystem::path m_fname;
ssize_t m_rows{};
ssize_t m_cols{};
ssize_t n_frames{};
size_t m_rows{};
size_t m_cols{};
size_t n_frames{};
int m_sub_file_index_{};
};

View File

@ -6,7 +6,7 @@
namespace aare {
File::File(std::filesystem::path fname, std::string mode, FileConfig cfg) {
File::File(const std::filesystem::path &fname, const std::string &mode, FileConfig cfg) {
if (mode != "r" && mode != "w" && mode != "a") {
throw std::invalid_argument("Unsupported file mode");
}
@ -36,20 +36,17 @@ void File::read_into(std::byte *image_buf) { file_impl->read_into(image_buf); }
void File::read_into(std::byte *image_buf, size_t n_frames) { file_impl->read_into(image_buf, n_frames); }
size_t File::frame_number(size_t frame_index) { return file_impl->frame_number(frame_index); }
size_t File::bytes_per_frame() { return file_impl->bytes_per_frame(); }
size_t File::pixels() { return file_impl->pixels(); }
size_t File::pixels_per_frame() { return file_impl->pixels_per_frame(); }
void File::seek(size_t frame_number) { file_impl->seek(frame_number); }
size_t File::tell() const { return file_impl->tell(); }
ssize_t File::rows() const { return file_impl->rows(); }
ssize_t File::cols() const { return file_impl->cols(); }
ssize_t File::bitdepth() const { return file_impl->bitdepth(); }
size_t File::rows() const { return file_impl->rows(); }
size_t File::cols() const { return file_impl->cols(); }
size_t File::bitdepth() const { return file_impl->bitdepth(); }
File::~File() { delete file_impl; }
Frame File::iread(size_t frame_number) { return file_impl->iread(frame_number); }
File::File(File &&other) {
file_impl = other.file_impl;
other.file_impl = nullptr;
}
File::File(File &&other) noexcept : file_impl(other.file_impl) { other.file_impl = nullptr; }
// write move assignment operator

View File

@ -26,6 +26,9 @@ NumpyFile::NumpyFile(const std::filesystem::path &fname, const std::string &mode
}
initial_header_len = aare::NumpyHelpers::write_header(std::filesystem::path(m_fname.c_str()), m_header);
}
m_pixels_per_frame = std::accumulate(m_header.shape.begin() + 1, m_header.shape.end(), 1, std::multiplies<>());
m_bytes_per_frame = m_header.dtype.bitdepth() / 8 * m_pixels_per_frame;
}
void NumpyFile::write(Frame &frame) {
@ -33,10 +36,14 @@ void NumpyFile::write(Frame &frame) {
throw std::runtime_error("File not open");
}
if (not(m_mode == "w" or m_mode == "a")) {
throw std::runtime_error("File not open for writing");
throw std::invalid_argument("File not open for writing");
}
if (fseek(fp, 0, SEEK_END))
throw std::runtime_error("Could not seek to end of file");
size_t const rc = fwrite(frame.data(), frame.size(), 1, fp);
if (rc != 1) {
throw std::runtime_error("Error writing frame to file");
}
fseek(fp, 0, SEEK_END);
fwrite(frame.data(), frame.size(), 1, fp);
}
Frame NumpyFile::get_frame(size_t frame_number) {
@ -49,16 +56,19 @@ void NumpyFile::get_frame_into(size_t frame_number, std::byte *image_buf) {
throw std::runtime_error("File not open");
}
if (frame_number > m_header.shape[0]) {
throw std::runtime_error("Frame number out of range");
throw std::invalid_argument("Frame number out of range");
}
if (fseek(fp, header_size + frame_number * m_bytes_per_frame, SEEK_SET)) // NOLINT
throw std::runtime_error("Could not seek to frame");
size_t const rc = fread(image_buf, m_bytes_per_frame, 1, fp);
if (rc != 1) {
throw std::runtime_error("Error reading frame from file");
}
fseek(fp, header_size + frame_number * bytes_per_frame(), SEEK_SET);
fread(image_buf, bytes_per_frame(), 1, fp);
}
size_t NumpyFile::pixels() {
return std::accumulate(m_header.shape.begin() + 1, m_header.shape.end(), 1, std::multiplies<uint64_t>());
};
size_t NumpyFile::bytes_per_frame() { return m_header.dtype.bitdepth() / 8 * pixels(); };
size_t NumpyFile::pixels_per_frame() { return m_pixels_per_frame; };
size_t NumpyFile::bytes_per_frame() { return m_bytes_per_frame; };
std::vector<Frame> NumpyFile::read(size_t n_frames) {
// TODO: implement this in a more efficient way
@ -73,30 +83,39 @@ void NumpyFile::read_into(std::byte *image_buf, size_t n_frames) {
// TODO: implement this in a more efficient way
for (size_t i = 0; i < n_frames; i++) {
get_frame_into(current_frame++, image_buf);
image_buf += bytes_per_frame();
image_buf += m_bytes_per_frame;
}
}
NumpyFile::~NumpyFile() {
NumpyFile::~NumpyFile() noexcept {
if (m_mode == "w" or m_mode == "a") {
// determine number of frames
fseek(fp, 0, SEEK_END);
size_t file_size = ftell(fp);
size_t data_size = file_size - initial_header_len;
size_t n_frames = data_size / bytes_per_frame();
if (fseek(fp, 0, SEEK_END)) {
aare::logger::error("Could not seek to end of file");
}
size_t const file_size = ftell(fp);
size_t const data_size = file_size - initial_header_len;
size_t const n_frames = data_size / m_bytes_per_frame;
// update number of frames in header (first element of shape)
m_header.shape[0] = n_frames;
fseek(fp, 0, SEEK_SET);
if (fseek(fp, 0, SEEK_SET)) {
aare::logger::error("Could not seek to beginning of file");
}
// create string stream to contain header
std::stringstream ss;
aare::NumpyHelpers::write_header(ss, m_header);
std::string header_str = ss.str();
std::string const header_str = ss.str();
// write header
fwrite(header_str.c_str(), header_str.size(), 1, fp);
size_t const rc = fwrite(header_str.c_str(), header_str.size(), 1, fp);
if (rc != 1) {
aare::logger::error("Error writing header to numpy file in destructor");
}
}
if (fp != nullptr) {
fclose(fp);
if (fclose(fp)) {
aare::logger::error("Error closing file");
}
}
}
@ -104,17 +123,23 @@ void NumpyFile::load_metadata() {
// read magic number
std::array<char, 6> tmp{};
fread(tmp.data(), tmp.size(), 1, fp);
size_t rc = fread(tmp.data(), tmp.size(), 1, fp);
if (rc != 1) {
throw std::runtime_error("Error reading magic number");
}
if (tmp != aare::NumpyHelpers::magic_str) {
for (auto item : tmp)
fmt::print("{}, ", int(item));
fmt::print("{}, ", static_cast<int>(item));
fmt::print("\n");
throw std::runtime_error("Not a numpy file");
}
// read version
fread(reinterpret_cast<char *>(&major_ver_), sizeof(major_ver_), 1, fp);
fread(reinterpret_cast<char *>(&minor_ver_), sizeof(minor_ver_), 1, fp);
rc = fread(reinterpret_cast<char *>(&major_ver_), sizeof(major_ver_), 1, fp);
rc += fread(reinterpret_cast<char *>(&minor_ver_), sizeof(minor_ver_), 1, fp);
if (rc != 2) {
throw std::runtime_error("Error reading numpy version");
}
if (major_ver_ == 1) {
header_len_size = 2;
@ -125,7 +150,10 @@ void NumpyFile::load_metadata() {
}
// read header length
fread(reinterpret_cast<char *>(&header_len), header_len_size, 1, fp);
rc = fread(reinterpret_cast<char *>(&header_len), header_len_size, 1, fp);
if (rc != 1) {
throw std::runtime_error("Error reading header length");
}
header_size = aare::NumpyHelpers::magic_string_length + 2 + header_len_size + header_len;
if (header_size % 16 != 0) {
fmt::print("Warning: header length is not a multiple of 16\n");
@ -133,31 +161,34 @@ void NumpyFile::load_metadata() {
// read header
std::string header(header_len, '\0');
fread(header.data(), header_len, 1, fp);
rc = fread(header.data(), header_len, 1, fp);
if (rc != 1) {
throw std::runtime_error("Error reading header");
}
// parse header
std::vector<std::string> keys{"descr", "fortran_order", "shape"};
std::vector<std::string> const keys{"descr", "fortran_order", "shape"};
aare::logger::debug("original header: \"header\"");
auto dict_map = aare::NumpyHelpers::parse_dict(header, keys);
if (dict_map.size() == 0)
if (dict_map.empty())
throw std::runtime_error("invalid dictionary in header");
std::string descr_s = dict_map["descr"];
std::string fortran_s = dict_map["fortran_order"];
std::string shape_s = dict_map["shape"];
std::string const descr_s = dict_map["descr"];
std::string const fortran_s = dict_map["fortran_order"];
std::string const shape_s = dict_map["shape"];
std::string descr = aare::NumpyHelpers::parse_str(descr_s);
aare::DType dtype = aare::NumpyHelpers::parse_descr(descr);
std::string const descr = aare::NumpyHelpers::parse_str(descr_s);
aare::DType const dtype = aare::NumpyHelpers::parse_descr(descr);
// convert literal Python bool to C++ bool
bool fortran_order = aare::NumpyHelpers::parse_bool(fortran_s);
bool const fortran_order = aare::NumpyHelpers::parse_bool(fortran_s);
// parse the shape tuple
auto shape_v = aare::NumpyHelpers::parse_tuple(shape_s);
shape_t shape;
for (auto item : shape_v) {
auto dim = static_cast<unsigned long>(std::stoul(item));
for (const auto &item : shape_v) {
auto dim = static_cast<size_t>(std::stoul(item));
shape.push_back(dim);
}
m_header = {dtype, fortran_order, shape};

View File

@ -41,7 +41,7 @@ namespace NumpyHelpers {
std::unordered_map<std::string, std::string> parse_dict(std::string in, const std::vector<std::string> &keys) {
std::unordered_map<std::string, std::string> map;
if (keys.size() == 0)
if (keys.empty())
return map;
in = trim(in);
@ -55,12 +55,12 @@ std::unordered_map<std::string, std::string> parse_dict(std::string in, const st
std::vector<std::pair<size_t, std::string>> positions;
for (auto const &key : keys) {
size_t pos = in.find("'" + key + "'");
size_t const pos = in.find("'" + key + "'");
if (pos == std::string::npos)
throw std::runtime_error("Missing '" + key + "' key.");
std::pair<size_t, std::string> position_pair{pos, key};
std::pair<size_t, std::string> const position_pair{pos, key};
positions.push_back(position_pair);
}
@ -69,10 +69,10 @@ std::unordered_map<std::string, std::string> parse_dict(std::string in, const st
for (size_t i = 0; i < positions.size(); ++i) {
std::string raw_value;
size_t begin{positions[i].first};
size_t const begin{positions[i].first};
size_t end{std::string::npos};
std::string key = positions[i].second;
std::string const key = positions[i].second;
if (i + 1 < positions.size())
end = positions[i + 1].first;
@ -104,7 +104,7 @@ aare::DType parse_descr(std::string typestring) {
const char byteorder_c = typestring[0];
const char kind_c = typestring[1];
std::string itemsize_s = typestring.substr(2);
std::string const itemsize_s = typestring.substr(2);
if (!in_array(byteorder_c, endian_chars)) {
throw std::runtime_error("invalid typestring (byteorder)");
@ -130,11 +130,11 @@ bool parse_bool(const std::string &in) {
}
std::string get_value_from_map(const std::string &mapstr) {
size_t sep_pos = mapstr.find_first_of(":");
size_t const sep_pos = mapstr.find_first_of(':');
if (sep_pos == std::string::npos)
return "";
std::string tmp = mapstr.substr(sep_pos + 1);
std::string const tmp = mapstr.substr(sep_pos + 1);
return trim(tmp);
}
@ -180,12 +180,12 @@ std::string parse_str(const std::string &in) {
void write_magic(std::ostream &ostream, int version_major, int version_minor) {
ostream.write(magic_str.data(), magic_string_length);
ostream.put(version_major);
ostream.put(version_minor);
ostream.put(static_cast<char>(version_major));
ostream.put(static_cast<char>(version_minor));
}
template <typename T> inline std::string write_tuple(const std::vector<T> &v) {
if (v.size() == 0)
if (v.empty())
return "()";
std::ostringstream ss;
ss.imbue(std::locale("C"));
@ -211,36 +211,35 @@ template <typename T> inline std::string write_tuple(const std::vector<T> &v) {
inline std::string write_boolean(bool b) {
if (b)
return "True";
else
return "False";
}
inline std::string write_header_dict(const std::string &descr, bool fortran_order, const shape_t &shape) {
std::string s_fortran_order = write_boolean(fortran_order);
std::string shape_s = write_tuple(shape);
std::string const s_fortran_order = write_boolean(fortran_order);
std::string const shape_s = write_tuple(shape);
return "{'descr': '" + descr + "', 'fortran_order': " + s_fortran_order + ", 'shape': " + shape_s + ", }";
}
size_t write_header(std::filesystem::path fname, const NumpyHeader &header) {
size_t write_header(const std::filesystem::path &fname, const NumpyHeader &header) {
std::ofstream out(fname, std::ios::binary | std::ios::out);
return write_header(out, header);
}
size_t write_header(std::ostream &out, const NumpyHeader &header) {
std::string header_dict = write_header_dict(header.dtype.str(), header.fortran_order, header.shape);
std::string const header_dict = write_header_dict(header.dtype.str(), header.fortran_order, header.shape);
size_t length = magic_string_length + 2 + 2 + header_dict.length() + 1;
int version_major = 1;
int version_minor = 0;
if (length >= 255 * 255) {
if (length >= static_cast<size_t>(255) * 255) {
length = magic_string_length + 2 + 4 + header_dict.length() + 1;
version_major = 2;
version_minor = 0;
}
size_t padding_len = 16 - length % 16;
std::string padding(padding_len, ' ');
size_t const padding_len = 16 - length % 16;
std::string const padding(padding_len, ' ');
// write magic
write_magic(out, version_major, version_minor);

View File

@ -30,7 +30,7 @@ void RawFile::open_subfiles() {
for (size_t i = 0; i != n_subfiles; ++i) {
auto v = std::vector<SubFile *>(n_subfile_parts);
for (size_t j = 0; j != n_subfile_parts; ++j) {
v[j] = new SubFile(data_fname(i, j), m_type, subfile_rows, subfile_cols, bitdepth());
v[j] = new SubFile(data_fname(i, j), m_type, subfile_rows, subfile_cols, m_bitdepth);
}
subfiles.push_back(v);
}
@ -42,18 +42,18 @@ sls_detector_header RawFile::read_header(const std::filesystem::path &fname) {
if (!fp)
throw std::runtime_error(fmt::format("Could not open: {} for reading", fname.c_str()));
size_t rc = fread(reinterpret_cast<char *>(&h), sizeof(h), 1, fp);
fclose(fp);
size_t const rc = fread(reinterpret_cast<char *>(&h), sizeof(h), 1, fp);
if (rc != 1)
throw std::runtime_error("Could not read header from file");
throw std::runtime_error(LOCATION + "Could not read header from file");
if (fclose(fp)) {
throw std::runtime_error(LOCATION + "Could not close file");
}
return h;
}
bool RawFile::is_master_file(std::filesystem::path fpath) {
std::string stem = fpath.stem();
if (stem.find("_master_") != std::string::npos)
return true;
else
return false;
bool RawFile::is_master_file(const std::filesystem::path &fpath) {
std::string const stem = fpath.stem();
return stem.find("_master_") != std::string::npos;
}
void RawFile::find_number_of_subfiles() {
@ -62,7 +62,7 @@ void RawFile::find_number_of_subfiles() {
;
n_subfiles = n_mod;
}
inline std::filesystem::path RawFile::data_fname(int mod_id, int file_id) {
inline std::filesystem::path RawFile::data_fname(size_t mod_id, size_t file_id) {
return this->m_base_path / fmt::format("{}_d{}_f{}_{}.raw", this->m_base_name, file_id, mod_id, this->m_findex);
}
@ -86,10 +86,10 @@ void RawFile::find_geometry() {
r++;
c++;
m_rows = r * subfile_rows;
m_cols = c * subfile_cols;
m_rows = (r * subfile_rows);
m_cols = (c * subfile_cols);
m_rows += (r - 1) * cfg.module_gap_row;
m_rows += static_cast<size_t>((r - 1) * cfg.module_gap_row);
}
void RawFile::parse_metadata() {
@ -109,7 +109,7 @@ void RawFile::parse_metadata() {
} else {
throw std::runtime_error(LOCATION + "Unsupported file type");
}
n_subfile_parts = geometry.row * geometry.col;
n_subfile_parts = static_cast<size_t>(geometry.row) * geometry.col;
}
void RawFile::parse_json_metadata() {
@ -141,7 +141,7 @@ void RawFile::parse_raw_metadata() {
for (std::string line; std::getline(ifs, line);) {
if (line == "#Frame Header")
break;
auto pos = line.find(":");
auto pos = line.find(':');
auto key_pos = pos;
while (key_pos != std::string::npos && std::isspace(line[--key_pos]))
;
@ -183,7 +183,7 @@ void RawFile::parse_fname() {
m_base_path = m_fname.parent_path();
m_base_name = m_fname.stem();
m_ext = m_fname.extension();
auto pos = m_base_name.rfind("_");
auto pos = m_base_name.rfind('_');
m_findex = std::stoi(m_base_name.substr(pos + 1));
pos = m_base_name.find("_master_");
m_base_name.erase(pos);
@ -200,7 +200,7 @@ void RawFile::get_frame_into(size_t frame_number, std::byte *frame_buffer) {
if (frame_number > this->m_total_frames) {
throw std::runtime_error(LOCATION + "Frame number out of range");
}
int subfile_id = frame_number / this->max_frames_per_file;
size_t const subfile_id = frame_number / this->max_frames_per_file;
// create frame and get its buffer
if (this->geometry.col == 1) {
@ -214,11 +214,11 @@ void RawFile::get_frame_into(size_t frame_number, std::byte *frame_buffer) {
} else {
// create a buffer that will hold a the frame part
auto bytes_per_part = this->subfile_rows * this->subfile_cols * this->m_bitdepth / 8;
std::byte *part_buffer = new std::byte[bytes_per_part];
auto *part_buffer = new std::byte[bytes_per_part];
for (size_t part_idx = 0; part_idx != this->n_subfile_parts; ++part_idx) {
this->subfiles[subfile_id][part_idx]->get_part(part_buffer, frame_number % this->max_frames_per_file);
for (int cur_row = 0; cur_row < (this->subfile_rows); cur_row++) {
for (size_t cur_row = 0; cur_row < (this->subfile_rows); cur_row++) {
auto irow = cur_row + (part_idx / this->geometry.col) * this->subfile_rows;
auto icol = (part_idx % this->geometry.col) * this->subfile_cols;
auto dest = (irow * this->m_cols + icol);
@ -252,13 +252,13 @@ size_t RawFile::frame_number(size_t frame_index) {
if (frame_index > this->m_total_frames) {
throw std::runtime_error(LOCATION + "Frame number out of range");
}
int subfile_id = frame_index / this->max_frames_per_file;
size_t const subfile_id = frame_index / this->max_frames_per_file;
return this->subfiles[subfile_id][0]->frame_number(frame_index % this->max_frames_per_file);
}
RawFile::~RawFile() {
for (auto &vec : subfiles) {
for (auto subfile : vec) {
for (auto *subfile : vec) {
delete subfile;
}
}

View File

@ -7,12 +7,10 @@
namespace aare {
SubFile::SubFile(std::filesystem::path fname, DetectorType detector, ssize_t rows, ssize_t cols, uint16_t bitdepth) {
this->m_rows = rows;
this->m_cols = cols;
this->m_fname = fname;
this->m_bitdepth = bitdepth;
this->n_frames = std::filesystem::file_size(fname) / (sizeof(sls_detector_header) + rows * cols * bitdepth / 8);
SubFile::SubFile(const std::filesystem::path &fname, DetectorType detector, size_t rows, size_t cols, size_t bitdepth)
: m_bitdepth(bitdepth), m_fname(fname), m_rows(rows), m_cols(cols),
n_frames(std::filesystem::file_size(fname) / (sizeof(sls_detector_header) + rows * cols * bitdepth / 8)) {
if (read_impl_map.find({detector, bitdepth}) == read_impl_map.end()) {
auto error_msg = LOCATION + "No read_impl function found for detector: " + toString(detector) +
" and bitdepth: " + std::to_string(bitdepth);
@ -21,8 +19,8 @@ SubFile::SubFile(std::filesystem::path fname, DetectorType detector, ssize_t row
this->read_impl = read_impl_map.at({detector, bitdepth});
}
size_t SubFile::get_part(std::byte *buffer, int frame_number) {
if (frame_number >= n_frames or frame_number < 0) {
size_t SubFile::get_part(std::byte *buffer, size_t frame_number) {
if (frame_number >= n_frames) {
throw std::runtime_error("Frame number out of range");
}
// TODO: find a way to avoid opening and closing the file for each frame
@ -31,9 +29,11 @@ size_t SubFile::get_part(std::byte *buffer, int frame_number) {
if (!fp) {
throw std::runtime_error(fmt::format("Could not open: {} for reading", m_fname.c_str()));
}
fseek(fp, sizeof(sls_detector_header) + (sizeof(sls_detector_header) + bytes_per_part()) * frame_number, SEEK_SET);
fseek(fp, sizeof(sls_detector_header) + (sizeof(sls_detector_header) + bytes_per_part()) * frame_number, // NOLINT
SEEK_SET);
auto ret = (this->*read_impl)(buffer);
fclose(fp);
if (fclose(fp))
throw std::runtime_error(LOCATION + "Could not close file");
return ret;
}
@ -42,24 +42,24 @@ size_t SubFile::read_impl_normal(std::byte *buffer) { return fread(buffer, this-
template <typename DataType> size_t SubFile::read_impl_reorder(std::byte *buffer) {
std::vector<DataType> tmp(this->pixels_per_part());
size_t rc = fread(reinterpret_cast<char *>(&tmp[0]), this->bytes_per_part(), 1, this->fp);
size_t const rc = fread(reinterpret_cast<char *>(tmp.data()), this->bytes_per_part(), 1, this->fp);
int adc_nr[32] = {300, 325, 350, 375, 300, 325, 350, 375, 200, 225, 250, 275, 200, 225, 250, 275,
std::array<int, 32> const adc_nr = {300, 325, 350, 375, 300, 325, 350, 375, 200, 225, 250, 275, 200, 225, 250, 275,
100, 125, 150, 175, 100, 125, 150, 175, 0, 25, 50, 75, 0, 25, 50, 75};
int sc_width = 25;
int nadc = 32;
int pixels_per_sc = 5000;
int const sc_width = 25;
int const nadc = 32;
int const pixels_per_sc = 5000;
auto dst = reinterpret_cast<DataType *>(buffer);
int pixel = 0;
for (int i = 0; i != pixels_per_sc; ++i) {
for (int i_adc = 0; i_adc != nadc; ++i_adc) {
int col = adc_nr[i_adc] + (i % sc_width);
int row;
int const col = adc_nr[i_adc] + (i % sc_width);
int row = 0;
if ((i_adc / 4) % 2 == 0)
row = 199 - int(i / sc_width);
row = 199 - (i / sc_width);
else
row = 200 + int(i / sc_width);
row = 200 + (i / sc_width);
dst[col + row * 400] = tmp[pixel];
pixel++;
@ -72,15 +72,15 @@ template <typename DataType> size_t SubFile::read_impl_flip(std::byte *buffer) {
// read to temporary buffer
// TODO! benchmark direct reads
std::vector<std::byte> tmp(this->bytes_per_part());
size_t rc = fread(reinterpret_cast<char *>(&tmp[0]), this->bytes_per_part(), 1, this->fp);
size_t const rc = fread(reinterpret_cast<char *>(tmp.data()), this->bytes_per_part(), 1, this->fp);
// copy to place
const size_t start = this->m_cols * (this->m_rows - 1) * sizeof(DataType);
const size_t row_size = this->m_cols * sizeof(DataType);
auto dst = buffer + start;
auto src = &tmp[0];
auto *dst = buffer + start;
auto *src = tmp.data();
for (int i = 0; i != this->m_rows; ++i) {
for (size_t i = 0; i != this->m_rows; ++i) {
std::memcpy(dst, src, row_size);
dst -= row_size;
src += row_size;
@ -89,16 +89,18 @@ template <typename DataType> size_t SubFile::read_impl_flip(std::byte *buffer) {
return rc;
};
size_t SubFile::frame_number(int frame_index) {
size_t SubFile::frame_number(size_t frame_index) {
sls_detector_header h{};
fp = fopen(this->m_fname.c_str(), "r");
if (!fp)
throw std::runtime_error(fmt::format("Could not open: {} for reading", m_fname.c_str()));
fseek(fp, (sizeof(sls_detector_header) + bytes_per_part()) * frame_index, SEEK_SET);
size_t rc = fread(reinterpret_cast<char *>(&h), sizeof(h), 1, fp);
fclose(fp);
throw std::runtime_error(LOCATION + fmt::format("Could not open: {} for reading", m_fname.c_str()));
fseek(fp, (sizeof(sls_detector_header) + bytes_per_part()) * frame_index, SEEK_SET); // NOLINT
size_t const rc = fread(reinterpret_cast<char *>(&h), sizeof(h), 1, fp);
if (rc != 1)
throw std::runtime_error("Could not read header from file");
throw std::runtime_error(LOCATION + "Could not read header from file");
if (fclose(fp)) {
throw std::runtime_error(LOCATION + "Could not close file");
}
return h.frameNumber;
}

View File

@ -18,16 +18,16 @@ template <> simdjson_inline simdjson::simdjson_result<std::array<int, 4>> simdjs
if (error) {
return error;
}
std::array<int, 4> arr;
std::array<int, 4> arr{};
int i = 0;
for (auto v : array) {
int64_t val;
int64_t val = 0;
error = v.get_int64().get(val);
if (error) {
return error;
}
arr[i++] = val;
arr[i++] = static_cast<int>(val);
}
return arr;
}
@ -37,7 +37,7 @@ template <> simdjson_inline simdjson::simdjson_result<std::array<int, 4>> simdjs
* adds a check for 32bit overflow
*/
template <> simdjson_inline simdjson::simdjson_result<uint32_t> simdjson::ondemand::value::get() noexcept {
size_t val;
size_t val = 0;
auto error = get_uint64().get(val);
if (error) {
return error;
@ -70,9 +70,9 @@ simdjson::ondemand::value::get() noexcept {
if (error) {
return error;
}
std::string_view key_view = field.unescaped_key();
std::string key_str(key_view.data(), key_view.size());
std::string_view value_view = field.value().get_string();
std::string_view const key_view = field.unescaped_key();
std::string const key_str(key_view.data(), key_view.size());
std::string_view const value_view = field.value().get_string();
map[key_str] = {value_view.data(), value_view.size()};
}
return map;
@ -122,7 +122,7 @@ struct ZmqHeader {
uint8_t detType{0};
uint8_t version{0};
/** if rows of image should be flipped */
int flipRows{0};
int64_t flipRows{0};
/** quad type (eiger hardware specific) */
uint32_t quad{0};
/** true if complete image, else missing packets */

View File

@ -32,7 +32,7 @@ class ZmqSocket {
std::string m_endpoint;
int m_zmq_hwm{1000};
int m_timeout_ms{1000};
size_t m_potential_frame_size{1024 * 1024};
size_t m_potential_frame_size{static_cast<size_t>(1024) * 1024};
constexpr static size_t m_max_header_size = 1024;
char *m_header_buffer = new char[m_max_header_size];
};

View File

@ -19,7 +19,7 @@ namespace aare {
*/
class ZmqSocketReceiver : public ZmqSocket {
public:
ZmqSocketReceiver(const std::string &endpoint);
explicit ZmqSocketReceiver(const std::string &endpoint);
void connect();
std::vector<ZmqFrame> receive_n();

View File

@ -12,7 +12,7 @@ namespace aare {
*/
class ZmqSocketSender : public ZmqSocket {
public:
ZmqSocketSender(const std::string &endpoint);
explicit ZmqSocketSender(const std::string &endpoint);
void bind();
size_t send(const ZmqHeader &header, const std::byte *data, size_t size);
size_t send(const ZmqFrame &zmq_frame);

View File

@ -6,6 +6,7 @@
#include <string>
namespace aare {
/**
* @brief ZmqFrame structure
* wrapper class to contain a ZmqHeader and a Frame
@ -24,9 +25,9 @@ class NetworkError : public std::runtime_error {
const char *m_msg;
public:
NetworkError(const char *msg) : std::runtime_error(msg), m_msg(msg) {}
NetworkError(const std::string msg) : std::runtime_error(msg) { m_msg = strdup(msg.c_str()); }
virtual const char *what() const noexcept override { return m_msg; }
explicit NetworkError(const char *msg) : std::runtime_error(msg), m_msg(msg) {}
explicit NetworkError(const std::string &msg) : std::runtime_error(msg), m_msg(strdup(msg.c_str())) {}
const char *what() const noexcept override { return m_msg; }
};
} // namespace network_io

View File

@ -3,8 +3,6 @@
#include "simdjson.h"
using namespace simdjson;
// helper functions to write json
// append to string for better performance (not tested)
@ -37,11 +35,11 @@ void write_map(std::string &s, const std::string &key, const std::map<std::strin
s += "\"";
s += key;
s += "\": {";
for (auto &kv : value) {
for (const auto &kv : value) {
write_str(s, kv.first, kv.second);
}
// remove last comma or trailing spaces
for (int i = s.size() - 1; i >= 0; i--) {
for (size_t i = s.size() - 1; i > 0; i--) {
if (s[i] == ',' or s[i] == ' ') {
s.pop_back();
} else
@ -66,7 +64,7 @@ void write_array(std::string &s, const std::string &key, const std::array<int, 4
namespace aare {
std::string ZmqHeader::to_string() const {
std::string s = "";
std::string s;
s.reserve(1024);
s += "{";
write_digit(s, "data", data ? 1 : 0);
@ -108,78 +106,79 @@ std::string ZmqHeader::to_string() const {
return s;
}
void ZmqHeader::from_string(std::string &s) {
void ZmqHeader::from_string(std::string &s) { // NOLINT
simdjson::padded_string ps(s.c_str(), s.size());
ondemand::parser parser;
ondemand::document doc = parser.iterate(ps);
ondemand::object object = doc.get_object();
simdjson::padded_string const ps(s.c_str(), s.size());
simdjson::ondemand::parser parser;
simdjson::ondemand::document doc = parser.iterate(ps);
simdjson::ondemand::object object = doc.get_object();
for (auto field : object) {
std::string_view key = field.unescaped_key();
std::string_view const key = field.unescaped_key();
if (key == "data") {
data = uint64_t(field.value()) ? true : false;
data = static_cast<uint64_t>(field.value()) != 0;
} else if (key == "jsonversion") {
jsonversion = uint32_t(field.value());
jsonversion = static_cast<uint32_t>(field.value());
} else if (key == "dynamicRange") {
dynamicRange = uint32_t(field.value());
dynamicRange = static_cast<uint32_t>(field.value());
} else if (key == "fileIndex") {
fileIndex = uint64_t(field.value());
fileIndex = static_cast<uint64_t>(field.value());
} else if (key == "ndetx") {
ndetx = uint32_t(field.value());
ndetx = static_cast<uint32_t>(field.value());
} else if (key == "ndety") {
ndety = uint32_t(field.value());
ndety = static_cast<uint32_t>(field.value());
} else if (key == "npixelsx") {
npixelsx = uint32_t(field.value());
npixelsx = static_cast<uint32_t>(field.value());
} else if (key == "npixelsy") {
npixelsy = uint32_t(field.value());
npixelsy = static_cast<uint32_t>(field.value());
} else if (key == "size") {
size = uint32_t(field.value());
size = static_cast<uint32_t>(field.value());
} else if (key == "acqIndex") {
acqIndex = uint64_t(field.value());
acqIndex = static_cast<uint64_t>(field.value());
} else if (key == "frameIndex") {
frameIndex = uint64_t(field.value());
frameIndex = static_cast<uint64_t>(field.value());
} else if (key == "progress") {
progress = field.value().get_double();
} else if (key == "fname") {
std::string_view tmp = field.value().get_string();
std::string_view const tmp = field.value().get_string();
fname = {tmp.begin(), tmp.end()};
} else if (key == "frameNumber") {
frameNumber = uint64_t(field.value());
frameNumber = static_cast<uint64_t>(field.value());
} else if (key == "expLength") {
expLength = uint32_t(field.value());
expLength = static_cast<uint32_t>(field.value());
} else if (key == "packetNumber") {
packetNumber = uint32_t(field.value());
packetNumber = static_cast<uint32_t>(field.value());
} else if (key == "detSpec1") {
detSpec1 = uint64_t(field.value());
detSpec1 = static_cast<uint64_t>(field.value());
} else if (key == "timestamp") {
timestamp = uint64_t(field.value());
timestamp = static_cast<uint64_t>(field.value());
} else if (key == "modId") {
modId = uint32_t(field.value());
modId = static_cast<uint32_t>(field.value());
} else if (key == "row") {
row = uint32_t(field.value());
row = static_cast<uint32_t>(field.value());
} else if (key == "column") {
column = uint32_t(field.value());
column = static_cast<uint32_t>(field.value());
} else if (key == "detSpec2") {
detSpec2 = uint32_t(field.value());
detSpec2 = static_cast<uint32_t>(field.value());
} else if (key == "detSpec3") {
detSpec3 = uint32_t(field.value());
detSpec3 = static_cast<uint32_t>(field.value());
} else if (key == "detSpec4") {
detSpec4 = uint32_t(field.value());
detSpec4 = static_cast<uint32_t>(field.value());
} else if (key == "detType") {
detType = uint32_t(field.value());
detType = static_cast<uint32_t>(field.value());
} else if (key == "version") {
version = uint32_t(field.value());
version = static_cast<uint32_t>(field.value());
} else if (key == "flipRows") {
flipRows = uint32_t(field.value());
flipRows = static_cast<int64_t>(field.value());
} else if (key == "quad") {
quad = uint32_t(field.value());
quad = static_cast<uint32_t>(field.value());
} else if (key == "completeImage") {
completeImage = uint64_t(field.value()) ? true : false;
completeImage = static_cast<uint64_t>(field.value()) != 0;
} else if (key == "addJsonHeader") {
addJsonHeader = std::map<std::string, std::string>(field.value());
addJsonHeader = static_cast<std::map<std::string, std::string>>(field.value());
} else if (key == "rx_roi") {
rx_roi = std::array<int, 4>(field.value());
rx_roi = static_cast<std::array<int, 4>>(field.value());
}
}
}

View File

@ -24,13 +24,13 @@ void ZmqSocketReceiver::connect() {
fmt::print("Setting ZMQ_RCVHWM to {}\n", m_zmq_hwm);
int rc = zmq_setsockopt(m_socket, ZMQ_RCVHWM, &m_zmq_hwm, sizeof(m_zmq_hwm)); // should be set before connect
if (rc)
throw network_io::NetworkError(fmt::format("Could not set ZMQ_RCVHWM: {}", strerror(errno)));
throw network_io::NetworkError(fmt::format("Could not set ZMQ_RCVHWM: {}", zmq_strerror(errno)));
int bufsize = m_potential_frame_size * m_zmq_hwm;
fmt::print("Setting ZMQ_RCVBUF to: {} MB\n", bufsize / (1024 * 1024));
size_t bufsize = m_potential_frame_size * m_zmq_hwm;
fmt::print("Setting ZMQ_RCVBUF to: {} MB\n", bufsize / (static_cast<size_t>(1024) * 1024));
rc = zmq_setsockopt(m_socket, ZMQ_RCVBUF, &bufsize, sizeof(bufsize));
if (rc)
throw network_io::NetworkError(fmt::format("Could not set ZMQ_RCVBUF: {}", strerror(errno)));
throw network_io::NetworkError(fmt::format("Could not set ZMQ_RCVBUF: {}", zmq_strerror(errno)));
zmq_connect(m_socket, m_endpoint.c_str());
zmq_setsockopt(m_socket, ZMQ_SUBSCRIBE, "", 0);
@ -44,7 +44,7 @@ ZmqHeader ZmqSocketReceiver::receive_header() {
// receive string ZmqHeader
aare::logger::debug("Receiving header");
size_t header_bytes_received = zmq_recv(m_socket, m_header_buffer, m_max_header_size, 0);
int const header_bytes_received = zmq_recv(m_socket, m_header_buffer, m_max_header_size, 0);
aare::logger::debug("Bytes: ", header_bytes_received);
m_header_buffer[header_bytes_received] = '\0'; // make sure we zero terminate
@ -71,9 +71,9 @@ ZmqHeader ZmqSocketReceiver::receive_header() {
* @return ZmqHeader
*/
int ZmqSocketReceiver::receive_data(std::byte *data, size_t size) {
int data_bytes_received = zmq_recv(m_socket, data, size, 0);
int const data_bytes_received = zmq_recv(m_socket, data, size, 0);
if (data_bytes_received == -1)
network_io::NetworkError("Got half of a multipart msg!!!");
throw network_io::NetworkError("Got half of a multipart msg!!!");
aare::logger::debug("Bytes: ", data_bytes_received);
return data_bytes_received;
@ -98,7 +98,7 @@ ZmqFrame ZmqSocketReceiver::receive_zmqframe() {
if (bytes_received == -1) {
throw network_io::NetworkError(LOCATION + "Error receiving frame");
}
if ((uint32_t)bytes_received != header.size) {
if (static_cast<uint32_t>(bytes_received) != header.size) {
throw network_io::NetworkError(
fmt::format("{} Expected {} bytes but received {}", LOCATION, header.size, bytes_received));
}
@ -113,7 +113,7 @@ std::vector<ZmqFrame> ZmqSocketReceiver::receive_n() {
std::vector<ZmqFrame> frames;
while (true) {
// receive header and frame
ZmqFrame zmq_frame = receive_zmqframe();
ZmqFrame const zmq_frame = receive_zmqframe();
if (!zmq_frame.header.data) {
break;
}

View File

@ -16,9 +16,9 @@ ZmqSocketSender::ZmqSocketSender(const std::string &endpoint) { m_endpoint = end
void ZmqSocketSender::bind() {
m_context = zmq_ctx_new();
m_socket = zmq_socket(m_context, ZMQ_PUB);
size_t rc = zmq_bind(m_socket, m_endpoint.c_str());
size_t const rc = zmq_bind(m_socket, m_endpoint.c_str());
if (rc != 0) {
std::string error = zmq_strerror(zmq_errno());
std::string const error = zmq_strerror(zmq_errno());
throw network_io::NetworkError("zmq_bind failed: " + error);
}
}
@ -31,11 +31,11 @@ void ZmqSocketSender::bind() {
* @return number of bytes sent
*/
size_t ZmqSocketSender::send(const ZmqHeader &header, const std::byte *data, size_t size) {
size_t rc;
size_t rc = 0;
// if (serialize_header) {
// rc = zmq_send(m_socket, &header, sizeof(ZmqHeader), ZMQ_SNDMORE);
// assert(rc == sizeof(ZmqHeader));
std::string header_str = header.to_string();
std::string const header_str = header.to_string();
aare::logger::debug("Header :", header_str);
rc = zmq_send(m_socket, header_str.c_str(), header_str.size(), ZMQ_SNDMORE);
assert(rc == header_str.size());
@ -43,7 +43,7 @@ size_t ZmqSocketSender::send(const ZmqHeader &header, const std::byte *data, siz
return rc;
}
size_t rc2 = zmq_send(m_socket, data, size, 0);
size_t const rc2 = zmq_send(m_socket, data, size, 0);
assert(rc2 == size);
return rc + rc2;
}
@ -56,11 +56,11 @@ size_t ZmqSocketSender::send(const ZmqHeader &header, const std::byte *data, siz
size_t ZmqSocketSender::send(const ZmqFrame &zmq_frame) {
const Frame &frame = zmq_frame.frame;
// send frame
size_t rc = send(zmq_frame.header, frame.data(), frame.size());
size_t const rc = send(zmq_frame.header, frame.data(), frame.size());
// send end of message header
ZmqHeader end_header = zmq_frame.header;
end_header.data = false;
size_t rc2 = send(end_header, nullptr, 0);
size_t const rc2 = send(end_header, nullptr, 0);
return rc + rc2;
}

View File

@ -20,7 +20,7 @@
*/
template <typename T> std::ostream &operator<<(std::ostream &out, const std::vector<T> &v) {
out << "[";
size_t last = v.size() - 1;
size_t const last = v.size() - 1;
for (size_t i = 0; i < v.size(); ++i) {
out << v[i];
if (i != last)
@ -71,9 +71,7 @@ template <typename K, typename V> std::ostream &operator<<(std::ostream &out, co
return out;
}
namespace aare {
namespace logger {
namespace aare::logger {
/**
* @brief enum to define the logging level
*/
@ -96,17 +94,14 @@ class Logger {
/**
* @brief get the instance of the logger
*/
Logger() {
standard_output = new std::ostream(standard_buf);
error_output = new std::ostream(error_buf);
}
Logger() : standard_output(new std::ostream(standard_buf)), error_output(new std::ostream(error_buf)) {} // NOLINT
/**
* @brief set the output file for the logger by filename
* @param filename name of the file to log to
* @return void
*/
void set_output_file(std::string filename) {
void set_output_file(const std::string &filename) {
if (out_file.is_open())
out_file.close();
out_file.open(filename);
@ -152,6 +147,10 @@ class Logger {
delete standard_output;
delete error_output;
}
Logger(Logger &&) noexcept = default;
Logger(const Logger &) = delete;
Logger &operator=(Logger &&) noexcept = default;
Logger &operator=(const Logger &) = delete;
/**
* @brief log a message
@ -199,9 +198,9 @@ class Logger {
*/
template <LOGGING_LEVEL level> void log_() {
if (level == LOGGING_LEVEL::ERROR) {
*error_output << std::endl;
*error_output << std::endl; // NOLINT
} else {
*standard_output << std::endl;
*standard_output << std::endl; // NOLINT
}
}
@ -217,10 +216,8 @@ class Logger {
template <LOGGING_LEVEL level, typename First, typename... Strings> void log_(First arg, const Strings... s) {
if (level == LOGGING_LEVEL::ERROR) {
*error_output << (arg) << ' ';
error_output->flush();
} else {
*standard_output << (arg) << ' ';
standard_output->flush();
}
log_<level>(s...);
}
@ -230,7 +227,7 @@ namespace internal {
/**
* @brief global instance of the logger
*/
extern aare::logger::Logger logger_instance;
extern aare::logger::Logger logger_instance; // NOLINT
} // namespace internal
/**
@ -270,9 +267,7 @@ template <typename... Strings> void error(const Strings... s) { internal::logger
extern void set_streams(std::streambuf *out, std::streambuf *err);
extern void set_streams(std::streambuf *out);
extern void set_verbosity(LOGGING_LEVEL level);
extern void set_output_file(std::string filename);
extern void set_output_file(const std::string &filename);
extern Logger &get_logger_instance();
} // namespace logger
} // namespace aare
} // namespace aare::logger

View File

@ -1,14 +1,12 @@
#include "aare/utils/logger.hpp"
namespace aare {
namespace logger {
namespace aare::logger {
namespace internal {
aare::logger::Logger logger_instance = aare::logger::Logger();
aare::logger::Logger logger_instance = aare::logger::Logger(); // NOLINT
} // namespace internal
void set_streams(std::streambuf *out, std::streambuf *err) { internal::logger_instance.set_streams(out, err); }
void set_streams(std::streambuf *out) { internal::logger_instance.set_streams(out); }
void set_verbosity(LOGGING_LEVEL level) { internal::logger_instance.set_verbosity(level); }
Logger &get_logger_instance() { return internal::logger_instance; }
void set_output_file(std::string filename) { internal::logger_instance.set_output_file(filename); }
} // namespace logger
} // namespace aare
void set_output_file(const std::string &filename) { internal::logger_instance.set_output_file(filename); }
} // namespace aare::logger