mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2025-06-20 02:57:13 +02:00
cpp Cluster and ClusterVector and ClusterFile are templated now, they support generic cluster types
This commit is contained in:
@ -4,8 +4,11 @@
|
||||
|
||||
namespace aare {
|
||||
|
||||
ClusterFile::ClusterFile(const std::filesystem::path &fname, size_t chunk_size,
|
||||
const std::string &mode)
|
||||
template <typename ClusterType,
|
||||
typename = std::enable_if_t<is_cluster_v<ClusterType>>>
|
||||
ClusterFile<ClusterType>::ClusterFile(const std::filesystem::path &fname,
|
||||
size_t chunk_size,
|
||||
const std::string &mode)
|
||||
: m_chunk_size(chunk_size), m_mode(mode) {
|
||||
|
||||
if (mode == "r") {
|
||||
@ -31,16 +34,21 @@ ClusterFile::ClusterFile(const std::filesystem::path &fname, size_t chunk_size,
|
||||
}
|
||||
}
|
||||
|
||||
ClusterFile::~ClusterFile() { close(); }
|
||||
template <typename ClusterType> ClusterFile<ClusterType>::~ClusterFile() {
|
||||
close();
|
||||
}
|
||||
|
||||
void ClusterFile::close() {
|
||||
template <typename ClusterType> void ClusterFile<ClusterType>::close() {
|
||||
if (fp) {
|
||||
fclose(fp);
|
||||
fp = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ClusterFile::write_frame(const ClusterVector<int32_t> &clusters) {
|
||||
// TODO generally supported for all clsuter types
|
||||
template <typename ClusterType>
|
||||
void ClusterFile<ClusterType>::write_frame(
|
||||
const ClusterVector<ClusterType> &clusters) {
|
||||
if (m_mode != "w" && m_mode != "a") {
|
||||
throw std::runtime_error("File not opened for writing");
|
||||
}
|
||||
@ -55,12 +63,14 @@ void ClusterFile::write_frame(const ClusterVector<int32_t> &clusters) {
|
||||
fwrite(clusters.data(), clusters.item_size(), clusters.size(), fp);
|
||||
}
|
||||
|
||||
ClusterVector<int32_t> ClusterFile::read_clusters(size_t n_clusters) {
|
||||
template <typename ClusterType>
|
||||
ClusterVector<ClusterType>
|
||||
ClusterFile<ClusterType>::read_clusters(size_t n_clusters) {
|
||||
if (m_mode != "r") {
|
||||
throw std::runtime_error("File not opened for reading");
|
||||
}
|
||||
|
||||
ClusterVector<int32_t> clusters(3, 3, n_clusters);
|
||||
ClusterVector<ClusterType> clusters(n_clusters);
|
||||
|
||||
int32_t iframe = 0; // frame number needs to be 4 bytes!
|
||||
size_t nph_read = 0;
|
||||
@ -108,12 +118,14 @@ ClusterVector<int32_t> ClusterFile::read_clusters(size_t n_clusters) {
|
||||
return clusters;
|
||||
}
|
||||
|
||||
ClusterVector<int32_t> ClusterFile::read_clusters(size_t n_clusters, ROI roi) {
|
||||
template <typename ClusterType>
|
||||
ClusterVector<ClusterType>
|
||||
ClusterFile<ClusterType>::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);
|
||||
ClusterVector<ClusterType> clusters;
|
||||
clusters.reserve(n_clusters);
|
||||
|
||||
int32_t iframe = 0; // frame number needs to be 4 bytes!
|
||||
@ -124,7 +136,7 @@ ClusterVector<int32_t> ClusterFile::read_clusters(size_t n_clusters, ROI roi) {
|
||||
// auto buf = reinterpret_cast<Cluster3x3 *>(clusters.data());
|
||||
// auto buf = clusters.data();
|
||||
|
||||
Cluster3x3 tmp; // this would break if the cluster size changes
|
||||
ClusterType tmp; // this would break if the cluster size changes
|
||||
|
||||
// if there are photons left from previous frame read them first
|
||||
if (nph) {
|
||||
@ -186,7 +198,8 @@ ClusterVector<int32_t> ClusterFile::read_clusters(size_t n_clusters, ROI roi) {
|
||||
return clusters;
|
||||
}
|
||||
|
||||
ClusterVector<int32_t> ClusterFile::read_frame() {
|
||||
template <typename ClusterType>
|
||||
ClusterVector<ClusterType> ClusterFile<ClusterType>::read_frame() {
|
||||
if (m_mode != "r") {
|
||||
throw std::runtime_error("File not opened for reading");
|
||||
}
|
||||
@ -204,7 +217,7 @@ ClusterVector<int32_t> ClusterFile::read_frame() {
|
||||
throw std::runtime_error("Could not read number of clusters");
|
||||
}
|
||||
// std::vector<Cluster3x3> clusters(n_clusters);
|
||||
ClusterVector<int32_t> clusters(3, 3, n_clusters);
|
||||
ClusterVector<ClusterType> clusters(n_clusters);
|
||||
clusters.set_frame_number(frame_number);
|
||||
|
||||
if (fread(clusters.data(), clusters.item_size(), n_clusters, fp) !=
|
||||
@ -372,8 +385,9 @@ Eta2 calculate_eta2(Cluster<T, ClusterSizeX, ClusterSizeY, CoordType> &cl) {
|
||||
Eta2 eta{};
|
||||
|
||||
// TODO loads of overhead for a 2x2 clsuter maybe keep 2x2 calculation
|
||||
size_t num_2x2_subclusters = (ClusterSizeX - 1) * (ClusterSizeY - 1);
|
||||
std::array<int32_t, num_2x2_subclusters> sum_2x2_subcluster;
|
||||
constexpr size_t num_2x2_subclusters =
|
||||
(ClusterSizeX - 1) * (ClusterSizeY - 1);
|
||||
std::array<T, num_2x2_subclusters> sum_2x2_subcluster;
|
||||
for (size_t i = 0; i < ClusterSizeY - 1; ++i) {
|
||||
for (size_t j = 0; j < ClusterSizeX - 1; ++j)
|
||||
sum_2x2_subcluster[i * (ClusterSizeX - 1) + j] =
|
||||
@ -383,9 +397,9 @@ Eta2 calculate_eta2(Cluster<T, ClusterSizeX, ClusterSizeY, CoordType> &cl) {
|
||||
cl.data[(i + 1) * ClusterSizeX + j + 1];
|
||||
}
|
||||
|
||||
auto c = std::max_element(sum_2x2_subclusters.begin(),
|
||||
sum_2x2_subcluster.end()) -
|
||||
sum_2x2_subcluster.begin();
|
||||
auto c =
|
||||
std::max_element(sum_2x2_subcluster.begin(), sum_2x2_subcluster.end()) -
|
||||
sum_2x2_subcluster.begin();
|
||||
|
||||
eta.sum = sum_2x2_subcluster[c];
|
||||
|
||||
@ -458,7 +472,6 @@ template <typename T> Eta2 calculate_eta2(Cluster<T, 3, 3> &cl) {
|
||||
eta.y = static_cast<double>(cl.data[7]) / (cl.data[7] + cl.data[4]);
|
||||
eta.c = cTopRight;
|
||||
break;
|
||||
// no default to allow compiler to warn about missing cases
|
||||
}
|
||||
return eta;
|
||||
}
|
||||
@ -473,8 +486,9 @@ template <typename T> Eta2 calculate_eta2(Cluster<T, 2, 2> &cl) {
|
||||
return eta;
|
||||
}
|
||||
|
||||
int analyze_cluster(Cluster3x3 &cl, int32_t *t2, int32_t *t3, char *quad,
|
||||
double *eta2x, double *eta2y, double *eta3x,
|
||||
// TODO complicated API simplify?
|
||||
int analyze_cluster(Cluster<int32_t, 3, 3> &cl, int32_t *t2, int32_t *t3,
|
||||
char *quad, double *eta2x, double *eta2y, double *eta3x,
|
||||
double *eta3y) {
|
||||
|
||||
return analyze_data(cl.data, t2, t3, quad, eta2x, eta2y, eta3x, eta3y);
|
||||
|
@ -5,7 +5,8 @@ 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) {
|
||||
: 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(
|
||||
@ -51,35 +52,37 @@ Interpolator::Interpolator(NDView<double, 3> etacube, NDView<double, 1> xbins,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::vector<Photon> Interpolator::interpolate(const ClusterVector<int32_t>& clusters) {
|
||||
template <typename ClusterType,
|
||||
typename = std::enable_if_t<is_cluster_v<ClusterType>>>
|
||||
std::vector<Photon>
|
||||
Interpolator::interpolate(const ClusterVector<ClusterType> &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++){
|
||||
for (size_t i = 0; i < clusters.size(); i++) {
|
||||
|
||||
auto cluster = clusters.at(i);
|
||||
Eta2 eta = calculate_eta2(cluster);
|
||||
|
||||
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;
|
||||
|
||||
|
||||
// auto ie = nearest_index(m_energy_bins, photon.energy)-1;
|
||||
// auto ix = nearest_index(m_etabinsx, eta.x)-1;
|
||||
// auto iy = nearest_index(m_etabinsy, eta.y)-1;
|
||||
//Finding the index of the last element that is smaller
|
||||
//should work fine as long as we have many bins
|
||||
// auto iy = nearest_index(m_etabinsy, eta.y)-1;
|
||||
// Finding the index of the last element that is smaller
|
||||
// should work fine as long as we have many bins
|
||||
auto ie = last_smaller(m_energy_bins, photon.energy);
|
||||
auto ix = last_smaller(m_etabinsx, eta.x);
|
||||
auto iy = last_smaller(m_etabinsy, eta.y);
|
||||
auto iy = last_smaller(m_etabinsy, eta.y);
|
||||
|
||||
// fmt::print("ex: {}, ix: {}, iy: {}\n", ie, ix, iy);
|
||||
|
||||
|
||||
double dX, dY;
|
||||
int ex, ey;
|
||||
// cBottomLeft = 0,
|
||||
@ -100,44 +103,47 @@ std::vector<Photon> Interpolator::interpolate(const ClusterVector<int32_t>& clus
|
||||
dY = -1.;
|
||||
break;
|
||||
case cBottomRight:
|
||||
dX = 0.;
|
||||
dX = 0.;
|
||||
dY = -1.;
|
||||
break;
|
||||
}
|
||||
photon.x += m_ietax(ix, iy, 0)*2 + dX;
|
||||
photon.y += m_ietay(ix, iy, 0)*2 + dY;
|
||||
photon.x += m_ietax(ix, iy, 0) * 2 + dX;
|
||||
photon.y += m_ietay(ix, iy, 0) * 2 + dY;
|
||||
photons.push_back(photon);
|
||||
}
|
||||
}else if(clusters.cluster_size_x() == 2 || clusters.cluster_size_y() == 2){
|
||||
for (size_t i = 0; i<clusters.size(); i++){
|
||||
auto cluster = clusters.at<Cluster2x2>(i);
|
||||
Eta2 eta= calculate_eta2(cluster);
|
||||
|
||||
} else if (clusters.cluster_size_x() == 2 ||
|
||||
clusters.cluster_size_y() == 2) {
|
||||
for (size_t i = 0; i < clusters.size(); i++) {
|
||||
auto cluster = clusters.at(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
|
||||
// auto ie = nearest_index(m_energy_bins, photon.energy)-1;
|
||||
// auto ix = nearest_index(m_etabinsx, eta.x)-1;
|
||||
// auto iy = nearest_index(m_etabinsy, eta.y)-1;
|
||||
//Finding the index of the last element that is smaller
|
||||
//should work fine as long as we have many bins
|
||||
|
||||
// Now do some actual interpolation.
|
||||
// Find which energy bin the cluster is in
|
||||
// auto ie = nearest_index(m_energy_bins, photon.energy)-1;
|
||||
// auto ix = nearest_index(m_etabinsx, eta.x)-1;
|
||||
// auto iy = nearest_index(m_etabinsy, eta.y)-1;
|
||||
// Finding the index of the last element that is smaller
|
||||
// should work fine as long as we have many bins
|
||||
auto ie = last_smaller(m_energy_bins, photon.energy);
|
||||
auto ix = last_smaller(m_etabinsx, eta.x);
|
||||
auto iy = last_smaller(m_etabinsy, eta.y);
|
||||
auto iy = last_smaller(m_etabinsy, eta.y);
|
||||
|
||||
photon.x += m_ietax(ix, iy, 0)*2; //eta goes between 0 and 1 but we could move the hit anywhere in the 2x2
|
||||
photon.y += m_ietay(ix, iy, 0)*2;
|
||||
photon.x +=
|
||||
m_ietax(ix, iy, 0) * 2; // eta goes between 0 and 1 but we could
|
||||
// move the hit anywhere in the 2x2
|
||||
photon.y += m_ietay(ix, iy, 0) * 2;
|
||||
photons.push_back(photon);
|
||||
}
|
||||
|
||||
}else{
|
||||
throw std::runtime_error("Only 3x3 and 2x2 clusters are supported for interpolation");
|
||||
|
||||
} else {
|
||||
throw std::runtime_error(
|
||||
"Only 3x3 and 2x2 clusters are supported for interpolation");
|
||||
}
|
||||
|
||||
|
||||
return photons;
|
||||
}
|
||||
|
Reference in New Issue
Block a user