File: DataUtil.cpp

package info (click to toggle)
bornagain 23.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 103,936 kB
  • sloc: cpp: 423,131; python: 40,997; javascript: 11,167; awk: 630; sh: 318; ruby: 173; xml: 130; makefile: 51; ansic: 24
file content (100 lines) | stat: -rw-r--r-- 3,425 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      Device/Data/DataUtil.cpp
//! @brief     Implements namespace DataUtil.
//!
//! @homepage  http://www.bornagainproject.org
//! @license   GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
//  ************************************************************************************************

#include "Device/Data/DataUtil.h"
#include "Base/Axis/Frame.h"
#include "Base/Axis/Scale.h"
#include "Base/Math/Numeric.h"
#include "Base/Util/Assert.h"
#include "Device/Data/Datafield.h"
#include <algorithm>
#include <cmath>

double2d_t DataUtil::invertAxis(int axis, const double2d_t& original)
{
    double2d_t inverse = original;

    const size_t orig_rows = original.size();

    if (axis == 1) {
        for (size_t i = 0; i < orig_rows; ++i)
            inverse[i] = original[orig_rows - i - 1];
    } else if (axis == 0) {
        ASSERT(orig_rows > 0);
        const size_t orig_cols = original.front().size();
        for (size_t i = 0; i < orig_rows; ++i)
            for (size_t j = 0; j < orig_cols; ++j)
                inverse[i][j] = original[i][orig_cols - j - 1];
    } else
        ASSERT_NEVER;

    return inverse;
}

double2d_t DataUtil::transpose(const double2d_t& original)
{
    ASSERT(!original.empty());

    const size_t orig_rows = original.size();
    const size_t orig_cols = original.front().size();

    double2d_t transposed(orig_cols, std::vector<double>(orig_rows));

    for (size_t i = 0; i < orig_rows; ++i)
        for (size_t j = 0; j < orig_cols; ++j)
            transposed[j][i] = original[i][j];

    return transposed;
}

Datafield DataUtil::rotatedDatafield(const Datafield& data, int n)
{
    ASSERT(data.rank() == 2);
    n = (n % 4 + 4) & 3; // modulo 4, also for negative arguments
    if (n == 0)
        return data;

    const size_t N = data.size();
    const size_t nx = data.axis(0).size();
    const size_t ny = data.axis(1).size();
    std::vector<double> out(N);

    if (n == 1) {
        for (size_t iy = 0; iy < ny; ++iy)     // out-y along out-axis 0
            for (size_t ix = 0; ix < nx; ++ix) // out-x along out-axis 1
                out[(ny - 1 - iy) * nx + ix] = data[ix * ny + iy];
        return {std::vector<const Scale*>{data.axis(1).clone(), data.axis(0).clone()}, out};

    } else if (n == 2) {
        for (size_t i = 0; i < N; ++i)
            out[i] = data[N - 1 - i];
        return {std::vector<const Scale*>{data.axis(0).clone(), data.axis(1).clone()}, out};

    } else if (n == 3) {
        for (size_t iy = 0; iy < ny; ++iy)     // out-y along out-axis 0
            for (size_t ix = 0; ix < nx; ++ix) // out-x along out-axis 1
                out[iy * nx + (nx - 1 - ix)] = data[ix * ny + iy];
        return {std::vector<const Scale*>{data.axis(1).clone(), data.axis(0).clone()}, out};
    }
    ASSERT_NEVER;
}

Datafield DataUtil::relativeDifferenceField(const Datafield& dat, const Datafield& ref)
{
    ASSERT(dat.frame().hasSameSizes(ref.frame()));
    std::vector<double> out(dat.size());
    for (size_t i = 0; i < dat.size(); ++i)
        out[i] = Numeric::relativeDifference(dat[i], ref[i]);
    return {dat.frame(), out};
}