mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2025-04-23 23:30:02 +02:00
WIP
This commit is contained in:
parent
8ae6bb76f8
commit
5614cb4673
@ -346,6 +346,7 @@ set(SourceFiles
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/geo_helpers.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/NumpyFile.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/NumpyHelpers.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Interpolator.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/PixelMap.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RawFile.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RawSubFile.cpp
|
||||
|
@ -8,11 +8,17 @@
|
||||
|
||||
namespace aare {
|
||||
|
||||
//TODO! Template this?
|
||||
struct Cluster3x3 {
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
int32_t data[9];
|
||||
};
|
||||
struct Cluster2x2 {
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
int32_t data[4];
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
cBottomLeft = 0,
|
||||
@ -37,6 +43,7 @@ struct Eta2 {
|
||||
double x;
|
||||
double y;
|
||||
corner c;
|
||||
int32_t sum;
|
||||
};
|
||||
|
||||
struct ClusterAnalysis {
|
||||
@ -97,6 +104,8 @@ class ClusterFile {
|
||||
*/
|
||||
ClusterVector<int32_t> read_clusters(size_t n_clusters);
|
||||
|
||||
ClusterVector<int32_t> read_clusters(size_t n_clusters, ROI roi);
|
||||
|
||||
/**
|
||||
* @brief Read a single frame from the file and return the clusters. The
|
||||
* cluster vector will have the frame number set.
|
||||
@ -131,5 +140,6 @@ int analyze_cluster(Cluster3x3 &cl, int32_t *t2, int32_t *t3, char *quad,
|
||||
|
||||
NDArray<double, 2> calculate_eta2(ClusterVector<int> &clusters);
|
||||
Eta2 calculate_eta2(Cluster3x3 &cl);
|
||||
Eta2 calculate_eta2(Cluster2x2 &cl);
|
||||
|
||||
} // namespace aare
|
||||
|
@ -231,6 +231,10 @@ template <typename T, typename CoordType = int16_t> class ClusterVector {
|
||||
return *reinterpret_cast<V *>(element_ptr(i));
|
||||
}
|
||||
|
||||
template <typename V> const V &at(size_t i) const {
|
||||
return *reinterpret_cast<const V *>(element_ptr(i));
|
||||
}
|
||||
|
||||
const std::string_view fmt_base() const {
|
||||
// TODO! how do we match on coord_t?
|
||||
return m_fmt_base;
|
||||
|
29
include/aare/Interpolator.hpp
Normal file
29
include/aare/Interpolator.hpp
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
#include "aare/NDArray.hpp"
|
||||
#include "aare/NDView.hpp"
|
||||
#include "aare/ClusterVector.hpp"
|
||||
#include "aare/ClusterFile.hpp" //Cluster_3x3
|
||||
namespace aare{
|
||||
|
||||
struct Photon{
|
||||
double x;
|
||||
double y;
|
||||
double energy;
|
||||
};
|
||||
|
||||
class Interpolator{
|
||||
NDArray<double, 3> m_ietax;
|
||||
NDArray<double, 3> m_ietay;
|
||||
|
||||
NDArray<double, 1> m_etabinsx;
|
||||
NDArray<double, 1> m_etabinsy;
|
||||
NDArray<double, 1> m_energy_bins;
|
||||
public:
|
||||
Interpolator(NDView<double, 3> etacube, NDView<double, 1> xbins, NDView<double, 1> ybins, NDView<double, 1> ebins);
|
||||
NDArray<double, 3> get_ietax(){return m_ietax;}
|
||||
NDArray<double, 3> get_ietay(){return m_ietay;}
|
||||
|
||||
std::vector<Photon> interpolate(const ClusterVector<int32_t>& clusters);
|
||||
};
|
||||
|
||||
} // namespace aare
|
@ -7,6 +7,7 @@ from ._aare import Pedestal_d, Pedestal_f, ClusterFinder, VarClusterFinder
|
||||
from ._aare import DetectorType
|
||||
from ._aare import ClusterFile
|
||||
from ._aare import hitmap
|
||||
from ._aare import ROI
|
||||
|
||||
from ._aare import ClusterFinderMT, ClusterCollector, ClusterFileSink, ClusterVector_i
|
||||
|
||||
|
@ -1,50 +1,40 @@
|
||||
import sys
|
||||
sys.path.append('/home/l_msdetect/erik/aare/build')
|
||||
|
||||
|
||||
#Our normal python imports
|
||||
from pathlib import Path
|
||||
import matplotlib.pyplot as plt
|
||||
from mpl_toolkits.axes_grid1 import make_axes_locatable
|
||||
import numpy as np
|
||||
import boost_histogram as bh
|
||||
import time
|
||||
|
||||
import tifffile
|
||||
|
||||
import aare
|
||||
|
||||
data = np.random.normal(10, 1, 1000)
|
||||
|
||||
hist = bh.Histogram(bh.axis.Regular(10, 0, 20))
|
||||
hist.fill(data)
|
||||
#Directly import what we need from aare
|
||||
from aare import File, ClusterFile, hitmap
|
||||
from aare._aare import calculate_eta2, ClusterFinderMT, ClusterCollector
|
||||
|
||||
|
||||
x = hist.axes[0].centers
|
||||
y = hist.values()
|
||||
y_err = np.sqrt(y)+1
|
||||
res = aare.fit_gaus(x, y, y_err, chi2 = True)
|
||||
base = Path('/mnt/sls_det_storage/moench_data/tomcat_nanoscope_21042020/09_Moench_650um/')
|
||||
|
||||
# for f in base.glob('*'):
|
||||
# print(f.name)
|
||||
|
||||
|
||||
t_elapsed = time.perf_counter()-t0
|
||||
print(f'Histogram filling took: {t_elapsed:.3f}s {total_clusters/t_elapsed/1e6:.3f}M clusters/s')
|
||||
cluster_fname = base/'acq_interp_center_3.8Mfr_200V.clust'
|
||||
flatfield_fname = base/'flatfield_center_200_d0_f000000000000_0.clust'
|
||||
|
||||
histogram_data = hist3d.counts()
|
||||
x = hist3d.axes[2].edges[:-1]
|
||||
|
||||
y = histogram_data[100,100,:]
|
||||
xx = np.linspace(x[0], x[-1])
|
||||
# fig, ax = plt.subplots()
|
||||
# ax.step(x, y, where = 'post')
|
||||
|
||||
y_err = np.sqrt(y)
|
||||
y_err = np.zeros(y.size)
|
||||
y_err += 1
|
||||
|
||||
# par = fit_gaus2(y,x, y_err)
|
||||
# ax.plot(xx, gaus(xx,par))
|
||||
# print(par)
|
||||
|
||||
res = fit_gaus(y,x)
|
||||
res2 = fit_gaus(y,x, y_err)
|
||||
print(res)
|
||||
print(res2)
|
||||
cluster_fname.stat().st_size/1e6/4
|
||||
|
||||
image = np.zeros((400,400))
|
||||
with ClusterFile(cluster_fname, chunk_size = 1000000) as f:
|
||||
for clusters in f:
|
||||
test = hitmap(image.shape, clusters)
|
||||
break
|
||||
# image += hitmap(image.shape, clusters)
|
||||
# break
|
||||
print('We are back in python')
|
||||
# fig, ax = plt.subplots(figsize = (7,7))
|
||||
# im = ax.imshow(image)
|
||||
# im.set_clim(0,1)
|
98
python/src/aare.code-workspace
Normal file
98
python/src/aare.code-workspace
Normal file
@ -0,0 +1,98 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "../../.."
|
||||
},
|
||||
{
|
||||
"path": "../../../../slsDetectorPackage"
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"files.associations": {
|
||||
"compare": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"csignal": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"strstream": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"bitset": "cpp",
|
||||
"cfenv": "cpp",
|
||||
"charconv": "cpp",
|
||||
"chrono": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"complex": "cpp",
|
||||
"concepts": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"deque": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"set": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"source_location": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"format": "cpp",
|
||||
"fstream": "cpp",
|
||||
"future": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"numbers": "cpp",
|
||||
"ostream": "cpp",
|
||||
"ranges": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"span": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"stdfloat": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"text_encoding": "cpp",
|
||||
"thread": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeindex": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"valarray": "cpp",
|
||||
"variant": "cpp",
|
||||
"regex": "cpp",
|
||||
"*.ipp": "cpp"
|
||||
}
|
||||
}
|
||||
}
|
@ -20,7 +20,13 @@ template <typename T>
|
||||
void define_cluster_vector(py::module &m, const std::string &typestr) {
|
||||
auto class_name = fmt::format("ClusterVector_{}", typestr);
|
||||
py::class_<ClusterVector<T>>(m, class_name.c_str(), py::buffer_protocol())
|
||||
.def(py::init<int, int>())
|
||||
.def(py::init<int, int>(),
|
||||
py::arg("cluster_size_x") = 3, py::arg("cluster_size_y") = 3)
|
||||
.def("push_back",
|
||||
[](ClusterVector<T> &self, int x, int y, py::array_t<T> data) {
|
||||
// auto view = make_view_2d(data);
|
||||
self.push_back(x, y, reinterpret_cast<const std::byte*>(data.data()));
|
||||
})
|
||||
.def_property_readonly("size", &ClusterVector<T>::size)
|
||||
.def("item_size", &ClusterVector<T>::item_size)
|
||||
.def_property_readonly("fmt",
|
||||
@ -38,6 +44,8 @@ void define_cluster_vector(py::module &m, const std::string &typestr) {
|
||||
auto *vec = new std::vector<T>(self.sum_2x2());
|
||||
return return_vector(vec);
|
||||
})
|
||||
.def_property_readonly("cluster_size_x", &ClusterVector<T>::cluster_size_x)
|
||||
.def_property_readonly("cluster_size_y", &ClusterVector<T>::cluster_size_y)
|
||||
.def_property_readonly("capacity", &ClusterVector<T>::capacity)
|
||||
.def_property("frame_number", &ClusterVector<T>::frame_number,
|
||||
&ClusterVector<T>::set_frame_number)
|
||||
|
@ -31,6 +31,11 @@ void define_cluster_file_io_bindings(py::module &m) {
|
||||
auto v = new ClusterVector<int32_t>(self.read_clusters(n_clusters));
|
||||
return v;
|
||||
},py::return_value_policy::take_ownership)
|
||||
.def("read_clusters",
|
||||
[](ClusterFile &self, size_t n_clusters, ROI roi) {
|
||||
auto v = new ClusterVector<int32_t>(self.read_clusters(n_clusters, roi));
|
||||
return v;
|
||||
},py::return_value_policy::take_ownership)
|
||||
.def("read_frame",
|
||||
[](ClusterFile &self) {
|
||||
auto v = new ClusterVector<int32_t>(self.read_frame());
|
||||
|
@ -195,6 +195,8 @@ void define_file_io_bindings(py::module &m) {
|
||||
|
||||
py::class_<ROI>(m, "ROI")
|
||||
.def(py::init<>())
|
||||
.def(py::init<int64_t, int64_t, int64_t, int64_t>(), py::arg("xmin"),
|
||||
py::arg("xmax"), py::arg("ymin"), py::arg("ymax"))
|
||||
.def_readwrite("xmin", &ROI::xmin)
|
||||
.def_readwrite("xmax", &ROI::xmax)
|
||||
.def_readwrite("ymin", &ROI::ymin)
|
||||
|
58
python/src/interpolation.hpp
Normal file
58
python/src/interpolation.hpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include "aare/Interpolator.hpp"
|
||||
#include "aare/NDArray.hpp"
|
||||
#include "aare/NDView.hpp"
|
||||
#include "np_helper.hpp"
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
|
||||
namespace py = pybind11;
|
||||
void define_interpolation_bindings(py::module &m) {
|
||||
|
||||
PYBIND11_NUMPY_DTYPE(aare::Photon, x,y,energy);
|
||||
|
||||
py::class_<aare::Interpolator>(m, "Interpolator")
|
||||
.def(py::init([](py::array_t<double, py::array::c_style | py::array::forcecast> etacube, py::array_t<double> xbins,
|
||||
py::array_t<double> ybins, py::array_t<double> ebins) {
|
||||
return Interpolator(make_view_3d(etacube), make_view_1d(xbins),
|
||||
make_view_1d(ybins), make_view_1d(ebins));
|
||||
}))
|
||||
.def("get_ietax", [](Interpolator& self){
|
||||
auto*ptr = new NDArray<double,3>{};
|
||||
*ptr = self.get_ietax();
|
||||
return return_image_data(ptr);
|
||||
})
|
||||
.def("get_ietay", [](Interpolator& self){
|
||||
auto*ptr = new NDArray<double,3>{};
|
||||
*ptr = self.get_ietay();
|
||||
return return_image_data(ptr);
|
||||
})
|
||||
.def("interpolate", [](Interpolator& self, const ClusterVector<int32_t>& clusters){
|
||||
auto photons = self.interpolate(clusters);
|
||||
auto* ptr = new std::vector<Photon>{photons};
|
||||
return return_vector(ptr);
|
||||
});
|
||||
|
||||
// TODO! Evaluate without converting to double
|
||||
m.def(
|
||||
"hej",
|
||||
[]() {
|
||||
// auto boost_histogram = py::module_::import("boost_histogram");
|
||||
// py::object axis =
|
||||
// boost_histogram.attr("axis").attr("Regular")(10, 0.0, 10.0);
|
||||
// py::object histogram = boost_histogram.attr("Histogram")(axis);
|
||||
// return histogram;
|
||||
// return h;
|
||||
},
|
||||
R"(
|
||||
Evaluate a 1D Gaussian function for all points in x using parameters par.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : array_like
|
||||
The points at which to evaluate the Gaussian function.
|
||||
par : array_like
|
||||
The parameters of the Gaussian function. The first element is the amplitude, the second element is the mean, and the third element is the standard deviation.
|
||||
)");
|
||||
}
|
@ -9,6 +9,7 @@
|
||||
#include "cluster.hpp"
|
||||
#include "cluster_file.hpp"
|
||||
#include "fit.hpp"
|
||||
#include "interpolation.hpp"
|
||||
|
||||
//Pybind stuff
|
||||
#include <pybind11/pybind11.h>
|
||||
@ -31,5 +32,6 @@ PYBIND11_MODULE(_aare, m) {
|
||||
define_cluster_collector_bindings(m);
|
||||
define_cluster_file_sink_bindings(m);
|
||||
define_fit_bindings(m);
|
||||
define_interpolation_bindings(m);
|
||||
|
||||
}
|
@ -108,6 +108,79 @@ ClusterVector<int32_t> ClusterFile::read_clusters(size_t n_clusters) {
|
||||
return clusters;
|
||||
}
|
||||
|
||||
ClusterVector<int32_t> ClusterFile::read_clusters(size_t n_clusters, ROI roi) {
|
||||
if (m_mode != "r") {
|
||||
throw std::runtime_error("File not opened for reading");
|
||||
}
|
||||
|
||||
ClusterVector<int32_t> clusters(3,3);
|
||||
clusters.reserve(n_clusters);
|
||||
|
||||
int32_t iframe = 0; // frame number needs to be 4 bytes!
|
||||
size_t nph_read = 0;
|
||||
uint32_t nn = m_num_left;
|
||||
uint32_t nph = m_num_left; // number of clusters in frame needs to be 4
|
||||
|
||||
// auto buf = reinterpret_cast<Cluster3x3 *>(clusters.data());
|
||||
// auto buf = clusters.data();
|
||||
|
||||
Cluster3x3 tmp; //this would break if the cluster size changes
|
||||
|
||||
// if there are photons left from previous frame read them first
|
||||
if (nph) {
|
||||
if (nph > n_clusters) {
|
||||
// if we have more photons left in the frame then photons to read we
|
||||
// read directly the requested number
|
||||
nn = n_clusters;
|
||||
} else {
|
||||
nn = nph;
|
||||
}
|
||||
//Read one cluster, in the ROI push back
|
||||
// nph_read += fread((buf + nph_read*clusters.item_size()),
|
||||
// clusters.item_size(), nn, fp);
|
||||
for(size_t i = 0; i < nn; i++){
|
||||
fread(&tmp, sizeof(tmp), 1, fp);
|
||||
if(tmp.x >= roi.xmin && tmp.x <= roi.xmax && tmp.y >= roi.ymin && tmp.y <= roi.ymax){
|
||||
clusters.push_back(tmp.x, tmp.y, reinterpret_cast<std::byte*>(tmp.data));
|
||||
nph_read++;
|
||||
}
|
||||
}
|
||||
|
||||
m_num_left = nph - nn; // write back the number of photons left
|
||||
}
|
||||
|
||||
if (nph_read < n_clusters) {
|
||||
// keep on reading frames and photons until reaching n_clusters
|
||||
while (fread(&iframe, sizeof(iframe), 1, fp)) {
|
||||
// read number of clusters in frame
|
||||
if (fread(&nph, sizeof(nph), 1, fp)) {
|
||||
if (nph > (n_clusters - nph_read))
|
||||
nn = n_clusters - nph_read;
|
||||
else
|
||||
nn = nph;
|
||||
|
||||
// nph_read += fread((buf + nph_read*clusters.item_size()),
|
||||
// clusters.item_size(), nn, fp);
|
||||
for(size_t i = 0; i < nn; i++){
|
||||
fread(&tmp, sizeof(tmp), 1, fp);
|
||||
if(tmp.x >= roi.xmin && tmp.x <= roi.xmax && tmp.y >= roi.ymin && tmp.y <= roi.ymax){
|
||||
clusters.push_back(tmp.x, tmp.y, reinterpret_cast<std::byte*>(tmp.data));
|
||||
nph_read++;
|
||||
}
|
||||
}
|
||||
m_num_left = nph - nn;
|
||||
}
|
||||
if (nph_read >= n_clusters)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Resize the vector to the number of clusters.
|
||||
// No new allocation, only change bounds.
|
||||
clusters.resize(nph_read);
|
||||
return clusters;
|
||||
}
|
||||
|
||||
ClusterVector<int32_t> ClusterFile::read_frame() {
|
||||
if (m_mode != "r") {
|
||||
throw std::runtime_error("File not opened for reading");
|
||||
@ -268,11 +341,23 @@ ClusterVector<int32_t> ClusterFile::read_frame() {
|
||||
NDArray<double, 2> calculate_eta2(ClusterVector<int> &clusters) {
|
||||
//TOTO! make work with 2x2 clusters
|
||||
NDArray<double, 2> eta2({static_cast<int64_t>(clusters.size()), 2});
|
||||
for (size_t i = 0; i < clusters.size(); i++) {
|
||||
auto e = calculate_eta2(clusters.at<Cluster3x3>(i));
|
||||
eta2(i, 0) = e.x;
|
||||
eta2(i, 1) = e.y;
|
||||
|
||||
if (clusters.cluster_size_x() == 3 || clusters.cluster_size_y() == 3) {
|
||||
for (size_t i = 0; i < clusters.size(); i++) {
|
||||
auto e = calculate_eta2(clusters.at<Cluster3x3>(i));
|
||||
eta2(i, 0) = e.x;
|
||||
eta2(i, 1) = e.y;
|
||||
}
|
||||
}else if(clusters.cluster_size_x() == 2 || clusters.cluster_size_y() == 2){
|
||||
for (size_t i = 0; i < clusters.size(); i++) {
|
||||
auto e = calculate_eta2(clusters.at<Cluster2x2>(i));
|
||||
eta2(i, 0) = e.x;
|
||||
eta2(i, 1) = e.y;
|
||||
}
|
||||
}else{
|
||||
throw std::runtime_error("Only 3x3 and 2x2 clusters are supported");
|
||||
}
|
||||
|
||||
return eta2;
|
||||
}
|
||||
|
||||
@ -290,7 +375,7 @@ Eta2 calculate_eta2(Cluster3x3 &cl) {
|
||||
tot2[3] = cl.data[4] + cl.data[5] + cl.data[7] + cl.data[8];
|
||||
|
||||
auto c = std::max_element(tot2.begin(), tot2.end()) - tot2.begin();
|
||||
|
||||
eta.sum = tot2[c];
|
||||
switch (c) {
|
||||
case cBottomLeft:
|
||||
if ((cl.data[3] + cl.data[4]) != 0)
|
||||
@ -333,6 +418,19 @@ Eta2 calculate_eta2(Cluster3x3 &cl) {
|
||||
return eta;
|
||||
}
|
||||
|
||||
|
||||
Eta2 calculate_eta2(Cluster2x2 &cl) {
|
||||
Eta2 eta{};
|
||||
|
||||
eta.x = static_cast<double>(cl.data[0]) / (cl.data[0] + cl.data[1]);
|
||||
eta.y = static_cast<double>(cl.data[0]) / (cl.data[0] + cl.data[2]);
|
||||
eta.sum = cl.data[0] + cl.data[1] + cl.data[2]+ cl.data[3];
|
||||
eta.c = cBottomLeft; //TODO! This is not correct
|
||||
return eta;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int analyze_cluster(Cluster3x3 &cl, int32_t *t2, int32_t *t3, char *quad,
|
||||
double *eta2x, double *eta2y, double *eta3x,
|
||||
double *eta3y) {
|
||||
|
159
src/Interpolator.cpp
Normal file
159
src/Interpolator.cpp
Normal file
@ -0,0 +1,159 @@
|
||||
#include "aare/Interpolator.hpp"
|
||||
|
||||
namespace aare {
|
||||
|
||||
Interpolator::Interpolator(NDView<double, 3> etacube, NDView<double, 1> xbins,
|
||||
NDView<double, 1> ybins, NDView<double, 1> ebins)
|
||||
: m_ietax(etacube), m_ietay(etacube), m_etabinsx(xbins), m_etabinsy(ybins), m_energy_bins(ebins) {
|
||||
if (etacube.shape(0) != xbins.size() || etacube.shape(1) != ybins.size() ||
|
||||
etacube.shape(2) != ebins.size()) {
|
||||
throw std::invalid_argument(
|
||||
"The shape of the etacube does not match the shape of the bins");
|
||||
}
|
||||
|
||||
// Cumulative sum in the x direction, can maybe be combined with a copy?
|
||||
for (ssize_t k = 0; k < m_ietax.shape(2); k++) {
|
||||
for (ssize_t j = 0; j < m_ietax.shape(1); j++) {
|
||||
for (ssize_t i = 1; i < m_ietax.shape(0); i++) {
|
||||
m_ietax(i, j, k) += m_ietax(i - 1, j, k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize by the highest row, if norm less than 1 don't do anything
|
||||
for (ssize_t k = 0; k < m_ietax.shape(2); k++) {
|
||||
for (ssize_t j = 0; j < m_ietax.shape(1); j++) {
|
||||
auto val = m_ietax(m_ietax.shape(0) - 1, j, k);
|
||||
double norm = val < 1 ? 1 : val;
|
||||
for (ssize_t i = 0; i < m_ietax.shape(0); i++) {
|
||||
m_ietax(i, j, k) /= norm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cumulative sum in the y direction
|
||||
for (ssize_t k = 0; k < m_ietay.shape(2); k++) {
|
||||
for (ssize_t i = 0; i < m_ietay.shape(0); i++) {
|
||||
for (ssize_t j = 1; j < m_ietay.shape(1); j++) {
|
||||
m_ietay(i, j, k) += m_ietay(i, j - 1, k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize by the highest column, if norm less than 1 don't do anything
|
||||
for (ssize_t k = 0; k < m_ietay.shape(2); k++) {
|
||||
for (ssize_t i = 0; i < m_ietay.shape(0); i++) {
|
||||
auto val = m_ietay(i, m_ietay.shape(1) - 1, k);
|
||||
double norm = val < 1 ? 1 : val;
|
||||
for (ssize_t j = 0; j < m_ietay.shape(1); j++) {
|
||||
m_ietay(i, j, k) /= norm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::vector<Photon> Interpolator::interpolate(const ClusterVector<int32_t>& clusters) {
|
||||
std::vector<Photon> photons;
|
||||
photons.reserve(clusters.size());
|
||||
|
||||
if (clusters.cluster_size_x() == 3 || clusters.cluster_size_y() == 3) {
|
||||
for (size_t i = 0; i<clusters.size(); i++){
|
||||
|
||||
auto cluster = clusters.at<Cluster3x3>(i);
|
||||
Eta2 eta= calculate_eta2(cluster);
|
||||
|
||||
Photon photon;
|
||||
photon.x = cluster.x;
|
||||
photon.y = cluster.y;
|
||||
photon.energy = eta.sum;
|
||||
|
||||
//Now do some actual interpolation.
|
||||
//Find which energy bin the cluster is in
|
||||
//TODO! Could we use boost-histogram Axis.index here?
|
||||
ssize_t idx = std::lower_bound(m_energy_bins.begin(), m_energy_bins.end(), photon.energy)-m_energy_bins.begin();
|
||||
auto ix = std::lower_bound(m_etabinsx.begin(), m_etabinsx.end(), eta.x)- m_etabinsx.begin();
|
||||
auto iy = std::lower_bound(m_etabinsy.begin(), m_etabinsy.end(), eta.y)- m_etabinsy.begin();
|
||||
|
||||
|
||||
// ibx=(np.abs(etabinsx - ex)).argmin() #Find out which bin the eta should land in
|
||||
// iby=(np.abs(etabinsy - ey)).argmin()
|
||||
double dX, dY;
|
||||
int ex, ey;
|
||||
// cBottomLeft = 0,
|
||||
// cBottomRight = 1,
|
||||
// cTopLeft = 2,
|
||||
// cTopRight = 3
|
||||
switch (eta.c) {
|
||||
case cTopLeft:
|
||||
dX = -1.;
|
||||
dY = 0;
|
||||
break;
|
||||
case cTopRight:;
|
||||
dX = 0;
|
||||
dY = 0;
|
||||
break;
|
||||
case cBottomLeft:
|
||||
dX = -1.;
|
||||
dY = -1.;
|
||||
break;
|
||||
case cBottomRight:
|
||||
dX = 0;
|
||||
dY = -1.;
|
||||
break;
|
||||
}
|
||||
photon.x += m_ietax(ix, iy, idx) + dX + 0.5;
|
||||
photon.y += m_ietay(ix, iy, idx) + dY + 0.5;
|
||||
|
||||
|
||||
// fmt::print("x: {}, y: {}, energy: {}\n", photon.x, photon.y, photon.energy);
|
||||
photons.push_back(photon);
|
||||
}
|
||||
}else if(clusters.cluster_size_x() == 2 || clusters.cluster_size_y() == 2){
|
||||
//TODO! Implement 2x2 interpolation
|
||||
for (size_t i = 0; i<clusters.size(); i++){
|
||||
|
||||
auto cluster = clusters.at<Cluster2x2>(i);
|
||||
Eta2 eta= calculate_eta2(cluster);
|
||||
|
||||
Photon photon;
|
||||
photon.x = cluster.x;
|
||||
photon.y = cluster.y;
|
||||
photon.energy = eta.sum;
|
||||
|
||||
//Now do some actual interpolation.
|
||||
//Find which energy bin the cluster is in
|
||||
//TODO! Could we use boost-histogram Axis.index here?
|
||||
ssize_t idx = std::lower_bound(m_energy_bins.begin(), m_energy_bins.end(), photon.energy)-m_energy_bins.begin();
|
||||
// auto ix = std::lower_bound(m_etabinsx.begin(), m_etabinsx.end(), eta.x)- m_etabinsx.begin();
|
||||
// auto iy = std::lower_bound(m_etabinsy.begin(), m_etabinsy.end(), eta.y)- m_etabinsy.begin();
|
||||
// if(ix<0) ix=0;
|
||||
// if(iy<0) iy=0;
|
||||
|
||||
auto find_index = [](NDArray<double, 1>& etabins, double val){
|
||||
auto iter = std::min_element(etabins.begin(), etabins.end(),
|
||||
[val,etabins](double a, double b) {
|
||||
return std::abs(a - val) < std::abs(b - val);
|
||||
});
|
||||
return std::distance(etabins.begin(), iter);
|
||||
};
|
||||
auto ix = find_index(m_etabinsx, eta.x)-1;
|
||||
auto iy = find_index(m_etabinsy, eta.y)-1;
|
||||
|
||||
photon.x += (1-m_ietax(ix, iy, idx))*2; //eta goes between 0 and 1 but we could move the hit anywhere in the 2x2
|
||||
photon.y += (1-m_ietay(ix, iy, idx))*2;
|
||||
|
||||
// photon.x = ix;
|
||||
// photon.y = iy;
|
||||
photons.push_back(photon);
|
||||
}
|
||||
|
||||
}else{
|
||||
throw std::runtime_error("Only 3x3 and 2x2 clusters are supported for interpolation");
|
||||
}
|
||||
|
||||
|
||||
return photons;
|
||||
}
|
||||
|
||||
} // namespace aare
|
@ -2,6 +2,7 @@
|
||||
#include <array>
|
||||
#include <catch2/benchmark/catch_benchmark.hpp>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <numeric>
|
||||
|
||||
using aare::NDArray;
|
||||
using aare::NDView;
|
||||
@ -34,6 +35,24 @@ TEST_CASE("Construct from an NDView") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("3D NDArray from NDView"){
|
||||
std::vector<int> data(27);
|
||||
std::iota(data.begin(), data.end(), 0);
|
||||
NDView<int, 3> view(data.data(), Shape<3>{3, 3, 3});
|
||||
NDArray<int, 3> image(view);
|
||||
REQUIRE(image.shape() == view.shape());
|
||||
REQUIRE(image.size() == view.size());
|
||||
REQUIRE(image.data() != view.data());
|
||||
|
||||
for(int64_t i=0; i<image.shape(0); i++){
|
||||
for(int64_t j=0; j<image.shape(1); j++){
|
||||
for(int64_t k=0; k<image.shape(2); k++){
|
||||
REQUIRE(image(i, j, k) == view(i, j, k));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("1D image") {
|
||||
std::array<int64_t, 1> shape{{20}};
|
||||
NDArray<short, 1> img(shape, 3);
|
||||
|
Loading…
x
Reference in New Issue
Block a user