LSSTApplications  18.1.0
LSSTDataManagementBasePackage
BaseColumnView.cc
Go to the documentation of this file.
1 #include "boost/preprocessor/seq/for_each.hpp"
2 #include "boost/preprocessor/tuple/to_seq.hpp"
3 
6 
7 namespace lsst {
8 namespace afw {
9 namespace table {
10 
11 // =============== BitsColumn implementation ================================================================
12 
13 namespace {
14 
15 struct MatchKey {
16  bool operator()(SchemaItem<Flag> const &item) const { return item.key == target; }
17 
18  explicit MatchKey(Key<Flag> const &t) : target(t) {}
19 
20  Key<Flag> const &target;
21 };
22 
23 struct MatchName {
24  bool operator()(SchemaItem<Flag> const &item) const { return item.field.getName() == target; }
25 
26  explicit MatchName(std::string const &t) : target(t) {}
27 
28  std::string const &target;
29 };
30 
31 } // namespace
32 
34  IntT r = std::find_if(_items.begin(), _items.end(), MatchKey(key)) - _items.begin();
35  if (std::size_t(r) == _items.size()) {
37  (boost::format("'%s' not found in BitsColumn") % key).str());
38  }
39  return r;
40 }
41 
43  IntT r = std::find_if(_items.begin(), _items.end(), MatchName(name)) - _items.begin();
44  if (std::size_t(r) == _items.size()) {
46  (boost::format("'%s' not found in BitsColumn") % name).str());
47  }
48  return r;
49 }
50 
51 BitsColumn::BitsColumn(int size) : _array(ndarray::allocate(size)) { _array.deep() = IntT(0); }
52 
53 // =============== BaseColumnView private Impl object =======================================================
54 
56  int recordCount; // number of records
57  void *buf; // pointer to the beginning of the first record's data
58  std::shared_ptr<BaseTable> table; // table that owns the records
59  ndarray::Manager::Ptr manager; // manages lifetime of 'buf'
60 
61  Impl(std::shared_ptr<BaseTable> const &table_, int recordCount_, void *buf_,
62  ndarray::Manager::Ptr const &manager_)
63  : recordCount(recordCount_), buf(buf_), table(table_), manager(manager_) {}
64 };
65 
66 // =============== BaseColumnView member function implementations ===========================================
67 
68 std::shared_ptr<BaseTable> BaseColumnView::getTable() const { return _impl->table; }
69 
70 template <typename T>
71 typename ndarray::ArrayRef<T, 1> const BaseColumnView::operator[](Key<T> const &key) const {
72  if (!key.isValid()) {
73  throw LSST_EXCEPT(
75  "Key is not valid (if this is a SourceCatalog, make sure slot aliases have been set up).");
76  }
77  return ndarray::external(reinterpret_cast<T *>(reinterpret_cast<char *>(_impl->buf) + key.getOffset()),
78  ndarray::makeVector(_impl->recordCount),
79  ndarray::makeVector(int(_impl->table->getSchema().getRecordSize() / sizeof(T))),
80  _impl->manager);
81 }
82 
83 template <typename T>
84 typename ndarray::ArrayRef<T, 2, 1> const BaseColumnView::operator[](Key<Array<T> > const &key) const {
85  if (!key.isValid()) {
86  throw LSST_EXCEPT(
88  "Key is not valid (if this is a SourceCatalog, make sure slot aliases have been set up).");
89  }
90  if (key.isVariableLength()) {
91  throw LSST_EXCEPT(pex::exceptions::LogicError, "Cannot get columns for variable-length array fields");
92  }
93  return ndarray::external(
94  reinterpret_cast<T *>(reinterpret_cast<char *>(_impl->buf) + key.getOffset()),
95  ndarray::makeVector(_impl->recordCount, key.getSize()),
96  ndarray::makeVector(int(_impl->table->getSchema().getRecordSize() / sizeof(T)), 1),
97  _impl->manager);
98 }
99 
100 ndarray::result_of::vectorize<detail::FlagExtractor, ndarray::Array<Field<Flag>::Element const, 1> >::type
102  if (!key.isValid()) {
103  throw LSST_EXCEPT(
105  "Key is not valid (if this is a SourceCatalog, make sure slot aliases have been set up).");
106  }
107  return ndarray::vectorize(detail::FlagExtractor(key),
108  ndarray::Array<Field<Flag>::Element const, 1>(ndarray::external(
109  reinterpret_cast<Field<Flag>::Element *>(
110  reinterpret_cast<char *>(_impl->buf) + key.getOffset()),
111  ndarray::makeVector(_impl->recordCount),
112  ndarray::makeVector(int(_impl->table->getSchema().getRecordSize() /
113  sizeof(Field<Flag>::Element))),
114  _impl->manager)));
115 }
116 
118  BitsColumn result(_impl->recordCount);
119  ndarray::ArrayRef<BitsColumn::IntT, 1, 1> array = result._array.deep();
120  if (keys.size() > sizeof(BitsColumn::IntT)) {
122  (boost::format("Too many keys passed to getBits(); %d > %d.") % keys.size() %
123  sizeof(BitsColumn::IntT))
124  .str());
125  }
126  BitsColumn::IntT const size = keys.size(); // just for unsigned/signed comparisons
127  for (BitsColumn::IntT i = 0; i < size; ++i) {
128  array |= (BitsColumn::IntT(1) << i) * (*this)[keys[i]];
129  result._items.push_back(getSchema().find(keys[i]));
130  }
131  return result;
132 }
133 
134 namespace {
135 
136 struct ExtractFlagItems {
137  template <typename T>
138  void operator()(SchemaItem<T> const &) const {}
139 
140  void operator()(SchemaItem<Flag> const &item) const { items->push_back(item); }
141 
143 };
144 
145 } // namespace
146 
148  BitsColumn result(_impl->recordCount);
149  ExtractFlagItems func = {&result._items};
150  getSchema().forEach(func);
151  if (result._items.size() > sizeof(BitsColumn::IntT)) {
153  (boost::format("Too many Flag keys in schema; %d > %d.") % result._items.size() %
154  sizeof(BitsColumn::IntT))
155  .str());
156  }
157  ndarray::ArrayRef<BitsColumn::IntT, 1, 1> array = result._array.deep();
158  BitsColumn::IntT const size = result._items.size(); // just for unsigned/signed comparisons
159  for (BitsColumn::IntT i = 0; i < size; ++i) {
160  array |= (BitsColumn::IntT(1) << i) * (*this)[result._items[i].key];
161  }
162  return result;
163 }
164 
169 
170 // needs to be in source file so it can (implicitly) call Impl's (implicit) dtor
172 
173 BaseColumnView::BaseColumnView(std::shared_ptr<BaseTable> const &table, int recordCount, void *buf,
174  ndarray::Manager::Ptr const &manager)
175  : _impl(std::make_shared<Impl>(table, recordCount, buf, manager)) {}
176 
177 // =============== Explicit instantiations ==================================================================
178 
179 #define INSTANTIATE_COLUMNVIEW_SCALAR(r, data, elem) \
180  template ndarray::ArrayRef<elem, 1> const BaseColumnView::operator[](Key<elem> const &) const;
181 
184 
185 #define INSTANTIATE_COLUMNVIEW_ARRAY(r, data, elem) \
186  template ndarray::ArrayRef<elem, 2, 1> const BaseColumnView::operator[](Key<Array<elem> > const &) const;
187 
190 } // namespace table
191 } // namespace afw
192 } // namespace lsst
#define AFW_TABLE_SCALAR_FIELD_TYPE_N
Definition: types.h:28
Column-wise view into a sequence of records that have been allocated contiguously.
A packed representation of a collection of Flag field columns.
int getOffset() const noexcept
Return the offset (in bytes) of this field within a record.
Definition: Key.h:87
BaseColumnView & operator=(BaseColumnView const &)
BitsColumn getAllBits() const
Return an integer array with all Flag fields repacked into individual bits.
std::shared_ptr< BaseTable > getTable() const
Return the table that owns the records.
Reports attempts to exceed implementation-defined length limits for some classes. ...
Definition: Runtime.h:76
IntT getBit(Key< Flag > const &key) const
py::object result
Definition: schema.cc:418
BitsColumn getBits(std::vector< Key< Flag > > const &keys) const
Return an integer array with the given Flag fields repacked into individual bits. ...
STL namespace.
bool isValid() const
Return true if the key was initialized to valid offset.
Definition: Flag.h:139
std::shared_ptr< BaseTable > table
bool isValid() const noexcept
Return true if the key was initialized to valid offset.
Definition: Key.h:97
STL class.
Reports attempts to access elements using an invalid key.
Definition: Runtime.h:151
Functor to compute a flag bit, used to create an ndarray expression template for flag columns...
A base class for image defects.
table::Key< int > type
Definition: Detector.cc:167
#define AFW_TABLE_SCALAR_FIELD_TYPE_TUPLE
Definition: types.h:31
#define AFW_TABLE_ARRAY_FIELD_TYPE_N
Definition: types.h:34
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:168
Impl(std::shared_ptr< BaseTable > const &table_, int recordCount_, void *buf_, ndarray::Manager::Ptr const &manager_)
A description of a field in a table.
Definition: Field.h:24
Tag types used to declare specialized field types.
Definition: misc.h:32
BaseColumnView(BaseColumnView const &)
Reports errors in the logical structure of the program.
Definition: Runtime.h:46
Key< Flag > const & target
ndarray::ArrayRef< T, 1 > const operator[](Key< T > const &key) const
Return a 1-d array corresponding to a scalar field (or subfield).
BOOST_PP_SEQ_FOR_EACH(INSTANTIATE_COLUMNVIEW_SCALAR, _, BOOST_PP_TUPLE_TO_SEQ(AFW_TABLE_SCALAR_FIELD_TYPE_N, AFW_TABLE_SCALAR_FIELD_TYPE_TUPLE)) BOOST_PP_SEQ_FOR_EACH(INSTANTIATE_COLUMNVIEW_ARRAY
T find_if(T... args)
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
#define INSTANTIATE_COLUMNVIEW_ARRAY(r, data, elem)
STL class.
A class used as a handle to a particular field in a table.
Definition: fwd.h:45
Key< U > key
Definition: Schema.cc:281
Key specialization for Flag.
Definition: Flag.h:94
#define INSTANTIATE_COLUMNVIEW_SCALAR(r, data, elem)
std::vector< SchemaItem< Flag > > * items
int getOffset() const
Return the offset in bytes of the integer element that holds this field&#39;s bit.
Definition: Flag.h:126
#define AFW_TABLE_ARRAY_FIELD_TYPE_TUPLE
Definition: types.h:36
A simple pair-like struct for mapping a Field (name and description) with a Key (used for actual data...
Definition: SchemaImpl.h:27