Skip to content

Instantly share code, notes, and snippets.

@parejkoj
Last active September 22, 2020 21:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save parejkoj/aa129417d693c67c668d512135270466 to your computer and use it in GitHub Desktop.
Save parejkoj/aa129417d693c67c668d512135270466 to your computer and use it in GitHub Desktop.
/**
* An immutable label for a filter in an exposure or coadd.
*
* This class is agnostic to whether the stored label is for an abstract or
* physical filter.
* Details about the filter bandpass and transmission curve are stored in a TransmissionCurve object, which
* can be looked up with the label via `butler.get("transmission_filter")`.
*/
class FilterLabel final : public typehandling::Storable {
public:
explicit FilterLabel(std::string const &label) _label(label) {}
/// Allow move and copy: this is a trivial object.
Filter(Filter const &) = default;
Filter(Filter &&) noexcept = default;
Filter &operator=(Filter const &) = default;
Filter &operator=(Filter &&) noexcept = default;
~Filter() noexcept = default;
/**
* Create a FilterLabel from a PropertySet (e.g. a FITS header)
*
* Reads the "FILTER" header keyword for the label.
*
* @param metadata Metadata to process (e.g. a FITS header)
*/
explicit FilterLabel(
std::shared_ptr<lsst::daf::base::PropertySet const> metadata);
std::string const &getLabel() const { return _label; }
/**
* Remap special characters, etc. to "_" for database fields.
*
* @return The filter label in database-sanatized format.
*/
std::string const &getDatabaseLabel() const;
/// Filters compare equal if their strings are equal.
bool operator==(FilterLabel const &rhs) const noexcept {
return _label == rhs.name;
}
bool operator!=(FilterLabel const &rhs) const noexcept {
return !(*this == rhs);
}
/// Return a hash of this object.
std::size_t hash_value() const noexcept override;
bool isPersistable() const noexcept override;
protected:
// Persistable support
std::string getPersistenceName() const override;
std::string getPythonModule() const override;
void write(OutputArchiveHandle &handle) const override;
private:
std::string _label;
};
std::string const &getLabel() { return _label; }
/**
* Remap special characters, etc. to "_" for database fields.
*
* @return The filter label in database-sanatized format.
*/
std::string const &getDatabaseLabel();
/// Filters compare equal if their strings are equal.
bool operator==(FilterLabel const &rhs) const noexcept {
return _label == rhs.name;
}
bool operator!=(FilterLabel const &rhs) const noexcept {
return !(*this == rhs);
}
/// Return a hash of this object.
std::size_t hash_value() const noexcept override;
bool isPersistable() const noexcept override;
protected:
// Persistable support
std::string getPersistenceName() const override;
std::string getPythonModule() const override;
void write(OutputArchiveHandle &handle) const override;
private:
std::string _label;
};
@kfindeisen
Copy link

kfindeisen commented Sep 2, 2020

This seems either too simple or too complex. Is this intended to be subclassed (since it's not final)? If not, why not just use a string, and have database-sanitizing as a function?

@parejkoj
Copy link
Author

parejkoj commented Sep 2, 2020

This is to support filter names in ExposureInfo. You're right, it probably should be final. Making it a class instead of a raw string lets us add a little functionality later.

I'm now thinking that getDatabaseName() should be in the python Continue-class though.

@kfindeisen
Copy link

kfindeisen commented Sep 2, 2020

We should probably have the same class functionality in both languages wherever possible; otherwise it's confusing. String manipulation doesn't seem like something that needs to be language-specific, even if C++'s string library is pretty clumsy.

@parejkoj
Copy link
Author

parejkoj commented Sep 2, 2020

That suggestion is to make coding this simpler: it'll be a lot simpler to write it in python, I think, and I'm almost positive we'd never need it in C++. Based on my searching, we essentially never do anything in C++ with the existing afw.image.Filter than newExposure.setFilter(exposure.getFilter()).

@kfindeisen
Copy link

kfindeisen commented Sep 2, 2020

I looked into it just now, and it looks like C++'s string handling has improved a lot in C++11; I think all we'd need to do is call std::regex_replace on all non-word characters. 🙂

@TallJimbo
Copy link

I think we probably want equality comparison, and of course the tricky part of this is persisting it into Exposure. Whether to enable or disable assignment is also worth thinking about, and that depends largely on whether this is going to be held by shared_ptr (to be like other ExposureInfo components, even if it's a tad wasteful for something this simple). Happy to defer to @kfindeisen on that, as he has a much more up-to-date view of the options and tradeoffs.

I think I'm with Krzysztof on getDatabaseName() being simpler in C++, but I also think that may just reflect a comfort level with C++ that he and I share with each other but not most of the DM team. In any case it is a simple enough question that we could fully code up both possibilities and then ask again.

@parejkoj
Copy link
Author

parejkoj commented Sep 9, 2020

The current afw Filter is held by ExposureInfo directly, not via shared_ptr. It's never not defined, so I don't see a reason to make it a pointer now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment