LSSTApplications  10.0-2-g4f67435,11.0.rc2+1,11.0.rc2+12,11.0.rc2+3,11.0.rc2+4,11.0.rc2+5,11.0.rc2+6,11.0.rc2+7,11.0.rc2+8
LSSTDataManagementBasePackage
Peak.cc
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 /*
3  * LSST Data Management System
4  * Copyright 2008-2014 LSST Corporation.
5  *
6  * This product includes software developed by the
7  * LSST Project (http://www.lsst.org/).
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the LSST License Statement and
20  * the GNU General Public License along with this program. If not,
21  * see <http://www.lsstcorp.org/LegalNotices/>.
22  */
23 #include <typeinfo>
24 
28 
29 namespace lsst { namespace afw { namespace detection {
30 
31 //-----------------------------------------------------------------------------------------------------------
32 //----- Private PeakTable/Record classes ---------------------------------------------------------------
33 //-----------------------------------------------------------------------------------------------------------
34 
35 // These private derived classes are what you actually get when you do PeakTable::make; like the
36 // private classes in BaseTable.cc, it's more convenient to have an extra set of trivial derived
37 // classes than to do a lot of friending.
38 
39 namespace {
40 
41 class PeakTableImpl;
42 
43 class PeakRecordImpl : public PeakRecord {
44 public:
45 
46  explicit PeakRecordImpl(PTR(PeakTable) const & table) : PeakRecord(table) {}
47 
48 };
49 
50 class PeakTableImpl : public PeakTable {
51 public:
52 
53  explicit PeakTableImpl(afw::table::Schema const & schema, PTR(afw::table::IdFactory) const & idFactory) :
54  PeakTable(schema, idFactory)
55  {}
56 
57  PeakTableImpl(PeakTableImpl const & other) : PeakTable(other) {}
58 
59 private:
60 
61  virtual PTR(afw::table::BaseTable) _clone() const {
62  return boost::make_shared<PeakTableImpl>(*this);
63  }
64 
65  virtual PTR(afw::table::BaseRecord) _makeRecord() {
66  PTR(PeakRecord) record = boost::make_shared<PeakRecordImpl>(getSelf<PeakTableImpl>());
67  if (getIdFactory()) record->setId((*getIdFactory())());
68  return record;
69  }
70 
71 };
72 
73 } // anonymous
74 
75 //-----------------------------------------------------------------------------------------------------------
76 //----- PeakFitsWriter ---------------------------------------------------------------------------------
77 //-----------------------------------------------------------------------------------------------------------
78 
79 // A custom FitsWriter for Peak - this just sets the AFW_TYPE key to PEAK, which should ensure
80 // we use PeakFitsReader to read it.
81 
82 namespace {
83 
84 class PeakFitsWriter : public afw::table::io::FitsWriter {
85 public:
86 
87  explicit PeakFitsWriter(Fits * fits, int flags) : afw::table::io::FitsWriter(fits, flags) {}
88 
89 protected:
90 
91  virtual void _writeTable(CONST_PTR(afw::table::BaseTable) const & table, std::size_t nRows);
92 
93 };
94 
95 void PeakFitsWriter::_writeTable(CONST_PTR(afw::table::BaseTable) const & t, std::size_t nRows) {
96  CONST_PTR(PeakTable) table = boost::dynamic_pointer_cast<PeakTable const>(t);
97  if (!table) {
98  throw LSST_EXCEPT(
99  lsst::pex::exceptions::LogicError,
100  "Cannot use a PeakFitsWriter on a non-Peak table."
101  );
102  }
104  _fits->writeKey("AFW_TYPE", "PEAK", "Tells lsst::afw to load this as a Peak table.");
105 }
106 
107 } // anonymous
108 
109 //-----------------------------------------------------------------------------------------------------------
110 //----- PeakFitsReader ---------------------------------------------------------------------------------
111 //-----------------------------------------------------------------------------------------------------------
112 
113 // A custom FitsReader for PeakTable/Record - this gets registered with name SIMPLE, so it should get used
114 // whenever we read a table with AFW_TYPE set to that value.
115 
116 namespace {
117 
118 class PeakFitsReader : public afw::table::io::FitsReader {
119 public:
120 
121  PeakFitsReader() : afw::table::io::FitsReader("PEAK") {}
122 
123  virtual PTR(afw::table::BaseTable) makeTable(
124  afw::table::io::FitsSchemaInputMapper & mapper,
125  PTR(daf::base::PropertyList) metadata,
126  int ioFlags,
127  bool stripMetadata
128  ) const {
129  PTR(PeakTable) table = PeakTable::make(mapper.finalize());
130  table->setMetadata(metadata);
131  return table;
132  }
133 
134 };
135 
136 // registers the reader so FitsReader::make can use it.
137 static PeakFitsReader const peakFitsReader;
138 
139 } // anonymous
140 
141 //-----------------------------------------------------------------------------------------------------------
142 //----- PeakTable/Record member function implementations -----------------------------------------------
143 //-----------------------------------------------------------------------------------------------------------
144 
145 PeakRecord::PeakRecord(PTR(PeakTable) const & table) : BaseRecord(table) {}
146 
147 std::ostream & operator<<(std::ostream & os, PeakRecord const & record) {
148  return os << (boost::format("%d: (%d,%d) (%.3f,%.3f)")
149  % record.getId()
150  % record.getIx() % record.getIy()
151  % record.getFx() % record.getFy());
152 }
153 
155  afw::table::Schema const & schema,
156  bool forceNewTable
157 ) {
158  typedef std::list< boost::weak_ptr<PeakTable> > CachedTableList;
159  static CachedTableList cache;
160  if (!checkSchema(schema)) {
161  throw LSST_EXCEPT(
162  lsst::pex::exceptions::InvalidParameterError,
163  "Schema for Peak must contain at least the keys defined by makeMinimalSchema()."
164  );
165  }
166  if (forceNewTable) {
167  return boost::make_shared<PeakTableImpl>(schema, afw::table::IdFactory::makeSimple());
168  }
169  CachedTableList::iterator iter = cache.begin();
170  while (iter != cache.end()) {
171  PTR(PeakTable) p = iter->lock();
172  if (!p) {
173  iter = cache.erase(iter);
174  } else {
175  if (p->getSchema().compare(schema, afw::table::Schema::IDENTICAL)
177  // Move the one we found to the front of the list, so it's easier to find
178  // the same thing repeatedly
179  if (iter != cache.begin()) {
180  cache.splice(cache.begin(), cache, iter);
181  }
182  return p;
183  }
184  ++iter;
185  }
186  }
187  // No match: we create a new table and put it in the cache
188  PTR(PeakTable) newTable = boost::make_shared<PeakTableImpl>(
190  );
191  cache.push_front(newTable);
192  return newTable;
193 }
194 
196  afw::table::BaseTable(schema), _idFactory(idFactory) {}
197 
199  afw::table::BaseTable(other),
200  _idFactory(other._idFactory ? other._idFactory->clone() : other._idFactory) {}
201 
203  id = schema.addField<afw::table::RecordId>("id", "unique ID");
204  fx = schema.addField<float>("f_x", "subpixel column position", "pixels");
205  fy = schema.addField<float>("f_y", "subpixel row position", "pixels");
206  ix = schema.addField<int>("i_x", "column position of highest pixel", "pixels");
207  iy = schema.addField<int>("i_y", "row position of highest pixel", "pixels");
208  peakValue = schema.addField<float>("peakValue", "value of [smoothed] image at peak position", "dn");
209  schema.getCitizen().markPersistent();
210 }
211 
213  static MinimalSchema it;
214  return it;
215 }
216 
218 PeakTable::makeFitsWriter(fits::Fits * fitsfile, int flags) const {
219  return boost::make_shared<PeakFitsWriter>(fitsfile, flags);
220 }
221 
222 } // namespace detection
223 
224 namespace table {
225 
226 
227 template class CatalogT<afw::detection::PeakRecord>;
228 template class CatalogT<afw::detection::PeakRecord const>;
229 
230 }}} // namespace lsst::afw::table
int iter
Defines the fields and offsets for a table.
Definition: Schema.h:46
Writer object for FITS binary tables.
Definition: FitsWriter.h:22
#define PTR(...)
Definition: base.h:41
std::ostream & operator<<(std::ostream &os, PeakRecord const &record)
Definition: Peak.cc:147
float getFx() const
Convenience accessors for the keys in the minimal schema.
Definition: Peak.h:214
Class for storing ordered metadata with comments.
Definition: PropertyList.h:81
Table class for Peaks in Footprints.
Definition: Peak.h:84
#define CONST_PTR(...)
Definition: base.h:47
Everything is the same.
Definition: Schema.h:67
daf::base::Citizen & getCitizen()
Get the Citizen corresponding to this Schema (SchemaImpl is what inherits from Citizen).
Definition: Schema.h:283
static boost::shared_ptr< IdFactory > makeSimple()
Return a simple IdFactory that simply counts from 1.
int getIy() const
Convenience accessors for the keys in the minimal schema.
Definition: Peak.h:210
std::map< Citizen const *, CitizenInfo > table
Definition: Citizen.h:93
void markPersistent(void)
Mark a Citizen as persistent and not destroyed until process end.
Definition: Citizen.cc:253
afw::table::Key< float > fx
Definition: Peak.h:182
static MinimalSchema & getMinimalSchema()
Definition: Peak.cc:212
afw::table::RecordId getId() const
Convenience accessors for the keys in the minimal schema.
Definition: Peak.h:206
if(width!=gim.getWidth()||height!=gim.getHeight()||x0!=gim.getX0()||y0!=gim.getY0())
Definition: saturated.cc:47
tbl::Schema schema
A polymorphic functor base class for generating record IDs for a table.
Definition: IdFactory.h:19
PeakTable(afw::table::Schema const &schema, boost::shared_ptr< afw::table::IdFactory > const &idFactory)
Definition: Peak.cc:195
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
Key< T > addField(Field< T > const &field, bool doReplace=false)
Add a new field to the Schema, and return the associated Key.
virtual void _writeTable(boost::shared_ptr< BaseTable const > const &table, std::size_t nRows)
Write a table and its schema.
afw::table::Key< float > fy
Definition: Peak.h:183
afw::table::Key< float > peakValue
Definition: Peak.h:186
float getFy() const
Convenience accessors for the keys in the minimal schema.
Definition: Peak.h:215
virtual boost::shared_ptr< afw::table::io::FitsWriter > makeFitsWriter(fits::Fits *fitsfile, int flags) const
Definition: Peak.cc:218
Record class that represents a peak in a Footprint.
Definition: Peak.h:40
boost::int64_t RecordId
Type used for unique IDs for records.
Definition: misc.h:21
int getIx() const
Convenience accessors for the keys in the minimal schema.
Definition: Peak.h:209