Created
December 17, 2014 16:18
-
-
Save jdswinbank/686c2988cae6ad6185cb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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