Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DM-41634: Add PixelMap subclass using AST mappings #15

Merged
merged 6 commits into from Dec 4, 2023

Conversation

cmsaunders
Copy link
Collaborator

No description provided.

@@ -17,6 +17,8 @@
#ifdef USE_YAML
#include "yaml-cpp/yaml.h"
#endif
#include "astshim.h"

#include "Std.h"
Copy link

@mwittgen mwittgen Nov 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is ugly in the original gbdes code that Std.h
Include all std headers and adding a using std

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it's not great, but we decided not to go through and change all the original code. New code is supposed to ignore this, but I forgot in the instance you commented on below.

class ASTMap: public PixelMap {
// Class representing a constant shift of position
public:
ASTMap(const ast::Mapping& mapping_, string name_=""):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is std::string obfuscated by the using std

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching this. We've been trying to include std:: in all new code, but I forgot and copied what was elsewhere in this file.


virtual PixelMap* duplicate() const;

~ASTMap() {}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be declared as default dtor

Suggested change
~ASTMap() {}
~ASTMap() = default;

astshim.h REQUIRED
HINTS $ENV{ASTSHIM_DIR}/include
)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't comment on this line below
This adds the target WCSfit as an executable
linking all static libs. astrometry which links astshim
Linking everything into one shlib gbdes might work and link this to this executable. Or remove
this target if it is not needed.

Suggested change
# add_subdirectory(src)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need an executable target here, unless @cmsaunders still finds it convenient for comparison-testing sometimes.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to just leave in instructions for how to build the executable if needed.

Copy link
Member

@TallJimbo TallJimbo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One possibly-major issue, but it should be straighftforward to fix.

astshim.h REQUIRED
HINTS $ENV{ASTSHIM_DIR}/include
)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need an executable target here, unless @cmsaunders still finds it convenient for comparison-testing sometimes.

double &xpix, double &ypix,
double color = astrometry::NODATA) const;

#ifdef USE_YAML
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know if USE_YAML is actually set in our builds? If not, it might be cleaner to leaf this block out entirely.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, yaml is built into the mappings and if USE_YAML is false some key classes don't get built. Long term, it would be nice to remove this dependence though.


static string type() {return "AST";}

ast::Mapping mapping;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better for this to be private.

// Class representing a constant shift of position
public:
ASTMap(const ast::Mapping& mapping_, std::string name_=""):
PixelMap(name_), mapping(mapping_) {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be much better to make the mapping data member a std::shared_ptr<ast::Mapping> and call copy() here. You don't actually care about being able to share pointers, and all else being equal I'd prefer unique_ptr, but once you have a shared_ptr (and that's what methods like Mapping::copy return) you're stuck with it. The important thing is that the mapping_ could be an instance of a derived class of Mapping, and by copy-constructing it you're slicing off any extra stuff the derived class might have added.

Normally that would result in really horrible bugs, and the copy constructor would have been disabled to protect against that, and I find it strange that that's not the case in Mapping. I'm sure it's related to the fact that the real inheritance is happening in AST C code and the C++ inheritance is just a facade around that, but I still think it's much safer to hold by pointer and avoid the type-slicing yourself.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I've implemented what you suggest. Can you check and see if I did what you meant? I also changed duplicate so that it no longer does a copy.

pydir/wcsfit.cpp Outdated
@@ -102,6 +103,10 @@ PYBIND11_MODULE(wcsfit, m) {
py::class_<astrometry::SubMap, astrometry::PixelMap>(m, "SubMap")
.def(py::init<list<astrometry::PixelMap *> const &, std::string, bool>());

py::class_<astrometry::ASTMap, astrometry::PixelMap>(m, "ASTMap")
.def(py::init<ast::Mapping, std::string>(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.def(py::init<ast::Mapping, std::string>(),
.def(py::init<ast::Mapping const &, std::string>(),

If this isn't marked as a reference or pointer we'll get more type-slicing in the pybind11 layer.

Copy link
Member

@timj timj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks okay in general. I'm worried about performance issues since this is a very non-optimal way of using AST with one transformation at a time.

@@ -332,5 +334,37 @@ namespace astrometry {
void operator=(const ColorTerm& rhs) = delete;

};

class ASTMap: public PixelMap {
// Class representing a constant shift of position
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why the ASTMap class is described as representing solely a constant shift.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a mistake due to my using a different class as a template.


#ifdef USE_YAML
// AST maps are not expected to be used for output, so we do not
// attempt to write a full description to yaml.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could, because AST mappings can be serialized to ASDF YAML.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know. I'm not going to implement that now, because I think it's pretty unlikely it will be needed.

double color) const {

std::vector<double> pixCoords{xpix, ypix};
std::vector<double> worldCoord = mapping.applyForward(pixCoords);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit worried that this is going to be slow. AST is much faster if you give it many coordinates to transform and it's even faster if you ask it to transform a regular pixel grid to WCS in one go (astMapGrid).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a timing test, and there is a slow-down, but it's not prohibitive. This will only be used in a couple places in setting up the astrometric fit. For 31 visits, the time it took to do source association went from ~4 seconds to ~7 seconds, and the fit initialization went from ~33 seconds to ~41 seconds.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. I assume it's not possible to run this in bulk given the way gbdes calls the transformation code, but I imagine it would pull all that time back if you did that.

Copy link
Member

@TallJimbo TallJimbo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small change requested with the new version, but the rest looks good.


PixelMap*
ASTMap::duplicate() const {
return new ASTMap(*mapping);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return new ASTMap(*mapping);
return new ASTMap(mapping->copy());

We want this to be a real deep copy, not a shallow copy of just the shared_ptr.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things--first isn’t mapping getting copied twice this way, because it gets copied again in the constructor? Second, should the constructor also be changed for this? As suggested, it doesn't compile
(no known conversion for argument 1 from 'std::shared_ptr<ast::Mapping>' to 'const ast::Mapping&').

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right - the copy is already there in the constructor, and we don't need another copy here. Ignore me.

@cmsaunders cmsaunders merged commit b5d82f1 into lsst-dev Dec 4, 2023
@cmsaunders cmsaunders deleted the tickets/DM-41634 branch December 4, 2023 19:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants