lsst.jointcal  21.0.0-19-g8edf490+12054a8c65
Histo4d.cc
Go to the documentation of this file.
1 // -*- LSST-C++ -*-
2 /*
3  * This file is part of jointcal.
4  *
5  * Developed for the LSST Data Management System.
6  * This product includes software developed by the LSST Project
7  * (https://www.lsst.org).
8  * See the COPYRIGHT file at the top-level directory of this distribution
9  * for details of code ownership.
10  *
11  * This program is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program. If not, see <https://www.gnu.org/licenses/>.
23  */
24 
25 #include <iostream>
26 #include <cmath>
27 #include <string.h> /* for memset*/
28 #include <algorithm> /* for sort */
29 #include <limits.h>
30 
31 #include "lsst/log/Log.h"
32 #include "lsst/jointcal/Histo4d.h"
33 
34 namespace {
35 LOG_LOGGER _log = LOG_GET("jointcal.Histo4d");
36 }
37 
38 namespace lsst {
39 namespace jointcal {
40 
41 SparseHisto4d::SparseHisto4d(const int n1, double min1, double max1, const int n2, double min2, double max2,
42  const int n3, double min3, double max3, const int n4, double min4, double max4,
43  const int nEntries) : _data(nEntries,0) {
44  double indexMax = n1 * n2 * n3 * n4;
45  if (indexMax > double(INT_MAX))
46  LOGLS_WARN(_log, "Cannot hold a 4D histo with more than " << INT_MAX << " values.");
47  _n[0] = n1;
48  _n[1] = n2;
49  _n[2] = n3;
50  _n[3] = n4;
51  _minVal[0] = min1;
52  _minVal[1] = min2;
53  _minVal[2] = min3;
54  _minVal[3] = min4;
55  _maxVal[0] = max1;
56  _maxVal[1] = max2;
57  _maxVal[2] = max3;
58  _maxVal[3] = max4;
59 
60  for (int i = 0; i < 4; ++i) _scale[i] = _n[i] / (_maxVal[i] - _minVal[i]);
61  _dataSize = nEntries;
62  _ndata = 0;
63  _sorted = false;
64 }
65 
66 int SparseHisto4d::code_value(const double x[4]) const {
67  int index = 0;
68  for (int idim = 0; idim < 4; ++idim) {
69  int i = (int)std::floor((x[idim] - _minVal[idim]) * _scale[idim]);
70  if (i < 0 || i >= _n[idim]) return -1;
71  index = index * _n[idim] + i;
72  }
73  return index;
74 }
75 
76 void SparseHisto4d::inverse_code(int code, double x[4]) const {
77  for (int i = 3; i >= 0; --i) {
78  int bin = code % _n[i];
79  code /= _n[i];
80  x[i] = _minVal[i] + ((double)bin + 0.5) / _scale[i];
81  }
82 }
83 
85  if (!_sorted) {
86  std::sort(_data.begin(), _data.end());
87  _sorted = true;
88  }
89 }
90 
91 void SparseHisto4d::fill(const double x[4])
92 
93 {
94  int code = code_value(x);
95  if (code < 0) return;
96  if (_ndata == _dataSize) {
97  _dataSize *= 2;
98  _data.resize(_dataSize);
99  }
100  _data[_ndata++] = code;
101  _sorted = false;
102 }
103 
104 void SparseHisto4d::fill(const double x1, const double x2, const double x3, const double x4) {
105  static double x[4];
106  x[0] = x1;
107  x[1] = x2;
108  x[2] = x3;
109  x[3] = x4;
110  fill(x);
111 }
112 
113 int SparseHisto4d::maxBin(double x[4]) {
114  sort();
115  if (_ndata == 0) return 0;
116  int maxval = _data[0];
117  int maxCount = 1;
118  int oldval = _data[0];
119  int currentCount = 1;
120  for (int i = 1; i < _ndata; ++i) {
121  if (_data[i] == oldval)
122  currentCount++;
123  else
124  currentCount = 1;
125  if (currentCount > maxCount) {
126  maxCount = currentCount;
127  maxval = _data[i];
128  }
129  oldval = _data[i];
130  }
131  inverse_code(maxval, x);
132  return maxCount;
133 }
134 
135 void SparseHisto4d::zeroBin(double x[4]) {
136  sort();
137  int code = code_value(x);
138  // inefficient locator...
139  int start = 0;
140  while ((_data[start] < code) && start < _ndata) start++;
141  // find how many identical entries we have
142  int end = std::min(start + 1, _ndata);
143  while (end < _ndata && _data[start] == _data[end]) end++;
144  int shift = end - start;
145  int lastShift = _ndata - (end - start);
146  for (int i = start; i < lastShift; ++i) _data[i] = _data[i + shift];
147  _ndata -= shift;
148 }
149 
150 void SparseHisto4d::binLimits(const double x[4], const int iDim, double &xMin, double &xMax) const {
151  int code = code_value(x);
152  double xCenter[4];
153  inverse_code(code, xCenter);
154  xMin = xCenter[iDim] - 0.5 / _scale[iDim];
155  xMax = xCenter[iDim] + 0.5 / _scale[iDim];
156 }
157 
158 void SparseHisto4d::print() const {
159  for (int i = 0; i < _ndata; ++i) // DEBUG
160  std::cout << _data[i] << ' ';
161  std::cout << std::endl;
162 }
163 } // namespace jointcal
164 } // namespace lsst
#define LOGLS_WARN(logger, message)
#define LOG_GET(logger)
int end
double x
T begin(T... args)
void zeroBin(double x[4])
Definition: Histo4d.cc:135
void inverse_code(const int code, double x[4]) const
Definition: Histo4d.cc:76
int maxBin(double x[4])
Definition: Histo4d.cc:113
void binLimits(const double x[4], const int idim, double &xMin, double &xMax) const
return the bin limits of dimension idim (0<=idim<4), around point X.
Definition: Histo4d.cc:150
void fill(const double x[4])
Definition: Histo4d.cc:91
int code_value(const double x[4]) const
Definition: Histo4d.cc:66
T end(T... args)
T endl(T... args)
T floor(T... args)
T min(T... args)
Class for a simple mapping implementing a generic AstrometryTransform.
T resize(T... args)
T sort(T... args)