Skip to content

Instantly share code, notes, and snippets.

@jdswinbank
Created December 17, 2014 16:18
Show Gist options
  • Save jdswinbank/686c2988cae6ad6185cb to your computer and use it in GitHub Desktop.
Save jdswinbank/686c2988cae6ad6185cb to your computer and use it in GitHub Desktop.
#include <iostream>
#include <cassert>
#include "lsst/afw/table.h"
#include "ndarray/eigen.h"
using namespace lsst::afw::table;
void populateCat(BaseCatalog & cat, int size = 3) {
auto schema = cat.getSchema();
auto k1 = schema.find<int>("f1").key;
auto k2 = schema.find<float>("f2").key;
auto k3 = schema.find<Array<double>>("f3").key;
for (int i = 1; i <= size; ++i) {
auto newRecord = cat.addNew();
newRecord->set(k1, i);
newRecord->set(k2, i*3.14);
ndarray::Array<double,1> a3 = (*newRecord)[k3]; // operator[] allows in-place edits for some fields
a3.asEigen().setRandom();
a3.deep() += i;
}
}
int main(void) {
// Set up an input schema with some example fields
Schema inputSchema;
Key<int> k1 = inputSchema.addField<int>("f1", "doc for f1");
Key<float> k2 = inputSchema.addField<float>("f2", "doc for f2", "units for f2");
Key< Array<double> > k3 = inputSchema.addField< Array<double> >("f3", "doc for f3", "units for f2", 5);
//
// Test 1: Extracting keys from a Catalog
//
// Here's a catalog based on inputSchema
BaseCatalog inputCatalog(inputSchema);
// Add some data, extracting keys from the catalogue & associated schema
populateCat(inputCatalog);
assert(inputCatalog.size() == 3);
//
// Test 2: Relationship between Schema, Catalog and Table
// Creating a Catalog implicitly creates an
// associated table.
//
// This Catalog uses the same Schema as above, but creates a new Table
BaseCatalog cat2(inputSchema);
// But is different, so should contain no data
assert(cat2.size() == 0);
// We can also create a Table independently
auto tab = BaseTable::make(inputSchema);
// And then use it to create a Catalog
BaseCatalog cat3(inputSchema);
populateCat(cat3, 26);
assert(cat3.size() == 26);
//
// Test 3: Using a SchemaMapper.
// My understanding is that a SchemaMapper enables us to map data
// between tables using different schemas by copying over some
// keys, but not others. However, so far I failed to make this
// work.
//
// Make a completely new schema for the output Table.
Schema outputSchema; // currently empty
assert(outputSchema.getFieldCount() == 0);
// We will use a SchemaMapper to copy from input to output
SchemaMapper mapper(inputSchema, outputSchema);
// Let's try mapping k1 from input to output; should return the key in the
// outputSchema.
Key<int> o1 = mapper.addMapping(k1);
// The output schema in the mapper is updated
assert(mapper.getOutputSchema().getFieldCount() == 1);
// But that is not the output schema we started with, which is unchanged
assert(outputSchema.getFieldCount() == 0);
// Ok, so in practice the above is not what we need: we can let the mapper
// create its own output schema and not bother feeding it one we have
// created.
mapper = SchemaMapper(inputSchema);
o1 = mapper.addMapping(k1);
assert(mapper.getOutputSchema().getFieldCount() == 1);
// Create an output catalog (and hence table) into which we are going to
// map the input.
BaseCatalog outputCatalog(mapper.getOutputSchema());
outputCatalog.copy();
// Here's some information about the output schema we are using
std::cout << "Output: " << outputCatalog.getSchema().getFieldCount()
<< " " << outputCatalog.getSchema().getRecordSize() << std::endl;
for (auto & s: outputCatalog.getSchema().getNames()) {
std::cout << s << std::endl;
}
// Iterate through the input and copy each record to the output using the
// mapper.
tab = inputCatalog.getTable();
for (auto it = inputCatalog.begin(); it < inputCatalog.end(); ++it) {
outputCatalog.push_back(tab->copyRecord(*it, mapper));
}
// And now iterate through the output and demonstrate we got the right
// thing
for (auto it = outputCatalog.begin(); it < outputCatalog.end(); ++it) {
std::cout << it->get(o1) << std::endl;
}
// But better would be to use a ColumnView to extract that information
// That's only possible if the Catalog is contiguous; we can make it so by
// copying (which is unfortunate...)
if (!outputCatalog.isContiguous()) {
auto temp = outputCatalog.copy();
outputCatalog = temp;
}
std::cout << outputCatalog.getColumnView()[o1];
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment