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-10777: Create TransformBoundedField #254

Merged
merged 11 commits into from Jul 10, 2017
Merged

DM-10777: Create TransformBoundedField #254

merged 11 commits into from Jul 10, 2017

Conversation

r-owen
Copy link
Contributor

@r-owen r-owen commented Jul 6, 2017

No description provided.

// -*- LSST-C++ -*-
/*
* LSST Data Management System
* Copyright 2017 LSST Corporation.
Copy link

Choose a reason for hiding this comment

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

Shouldn't this be different? A year range or so?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It starts out as the year of authorship. That is changed to a range for future edits in a later year.

Copy link

Choose a reason for hiding this comment

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

The template used to be different. But no problem, just curious.

Copy link
Contributor

Choose a reason for hiding this comment

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

It should be different — not because of the date, but because the copyright isn't held by LSST Corporation. Our usual convention is to use "Copyright NNNN AURA/LSST" (which is likely also incorrect, but at least it's in the template...).

/**
* Create a TransformBoundedField from a bounding box and transform.
*/
TransformBoundedField(geom::Box2I const& bbox, Transform const& transform);
Copy link

Choose a reason for hiding this comment

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

Add explicitly default (or deleted) copy and move constructors / assignment operators?

Copy link
Contributor Author

@r-owen r-owen Jul 7, 2017

Choose a reason for hiding this comment

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

Good point. I'll emulate Transform, which allows copying but not assignment. That said, I'm not certain if that's the best choice, and if you have an alternate suggestion let me know.

Transform getTransform() const { return _transform; }

/// @copydoc BoundedField::evaluate
virtual double evaluate(geom::Point2D const & position) const override;
Copy link

Choose a reason for hiding this comment

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

No need for the virtual here (clear from override) and leaving it out is what the style guide recommends (I think).


/// @copydoc BoundedField::evaluate
virtual ndarray::Array<double, 1, 1> evaluate(ndarray::Array<double const, 1> const& x,
ndarray::Array<double const, 1> const& y) const override;
Copy link

Choose a reason for hiding this comment

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

Same here, but this overload is not virtual in the base class.

Copy link
Contributor Author

@r-owen r-owen Jul 7, 2017

Choose a reason for hiding this comment

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

That was true before this ticket. I changed the array version of BoundedField::evaluate to virtual on this ticket, for this reason.

using BoundedField::evaluate;

/// TransformBoundedField is always persistable.
virtual bool isPersistable() const override { return true; }
Copy link

Choose a reason for hiding this comment

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

Same here (not marked for the rest).

import numpy as np
from numpy.testing import assert_allclose


Copy link

Choose a reason for hiding this comment

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

Remove newline?

lsst.afw.geom.Extent2I(5, 30))

# a list of points contained in the bbox
self.pointList = lsst.afw.geom.Box2D(self.bbox).getCorners()
Copy link

Choose a reason for hiding this comment

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

Are corners still considered to be in the box?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe so. In this case it doesn't matter -- the functional form of the transform has no intrinsic limits; the bbox is arbitrary.

# applylForward returns an array with one row of values per axis
# and in this case there is just one axis
predResArr = self.transform.applyForward(self.pointList)[0]
assert_allclose(resArr, predResArr)
Copy link

Choose a reason for hiding this comment

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

What about things outside of the box?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

BoundedField.evaluate does not checks limits, so such a test is not helpful.

assert_allclose(scaledField1.evaluate(self.xList, self.yList), predResult)

scaledField2 = multFactor * self.boundedField
assert_allclose(scaledField2.evaluate(self.xList, self.yList), predResult)
Copy link

Choose a reason for hiding this comment

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

What about very large, very small, negative or otherwise problematic or invalid multiplication factors?

Copy link
Contributor Author

@r-owen r-owen Jul 7, 2017

Choose a reason for hiding this comment

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

I'll add a few values. I don't want to try to overflow or anything like that, but a reasonble dynamic range of values seems wise.


self.assertTrue(self.boundedField == readField)
self.assertFalse(self.boundedField != readField)
self.assertEqual(self.boundedField, readField)
Copy link

Choose a reason for hiding this comment

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

Move equality tests up before the previous block.

@r-owen r-owen force-pushed the tickets/DM-10777 branch 2 times, most recently from e60b664 to 3a26ea4 Compare July 8, 2017 20:46
void writeStream(std::ostream & os) const override;

/// Serialize this SkyWcs to a string, using the same format as writeStream
virtual std::string writeString() const;
Copy link

Choose a reason for hiding this comment

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

override instead of virtual?

}

return Transform(*frameSet);
}
Copy link

Choose a reason for hiding this comment

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

Nice


template<class Transform>
void writeStream(Transform const & transform, std::ostream & os) {
os << "1 " << Transform::getShortClassName();
Copy link

@pschella pschella Jul 9, 2017

Choose a reason for hiding this comment

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

Please add a serializationVersion (or other name, perhaps just version) constexpr for the version magic number.

Copy link
Contributor Author

@r-owen r-owen Jul 10, 2017

Choose a reason for hiding this comment

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

OK. Given that I the unpersistence code is in the file, and has to use hard-coded numbers, I don't see a lot of gain, but I guess it beats writing an int as a string. I added serializationVersion as a constexpr int.

@r-owen r-owen force-pushed the tickets/DM-10777 branch 6 times, most recently from 7468dc2 to b3f722f Compare July 10, 2017 15:14
The set/unset characteristic of the Base and Current attributes
of the FrameSet were not being preserved by all of Transform's
constructors, causing unwanted failures in testing equality of
transforms (e.g. after persisting and unpersisting).
This will be used for persistence of Transform
and to simplify the pybind11 wrapper of Transform
and use it to simplify Transform's pybind11 wrapper.
This will also be used by Transform::readStream and writeStream
Add Transform and SkyWcs serialization methods readStream,
readString, writeStream and writeString. Only the string versions
are available in Python, since C++ streams are not easy to wrap.
The work is done by two new utility functions in transformUtils.h
so the code can be shared between Transform and SkyWcs.
Update unit tests accordingly.
Given the new Transform persistence methods, there is no need
for saveToFile.
and change it to read a string, not a file.
That matches the new persistence better
and is more general-purpose
Make `BoundedField::evaluate(ndarray::Array...` virtual so
`TransformBoundedField` can override it with
a more efficient implementation.
Move the ChebyshevBoundedFieldFactory constructor to the beginning
of the class methods and make it explicit.
and update the ChebyshevBoundedField wrapper accordingly.

Wrap `__ne__` for `BoundedField` to eliminate the need to wrap
it in subclasses. This was especially nasty because the
C++ method `operator!=` was only defined in `BoundedField`,
so it was easy to miss in wrappers of all subclasses,
and failure to wrap it resulted in errors that only showed
up in Python 2, not Python 3.
Wrap `__eq__` for `BoundedField`, even though it has no
implementation. This is best practice and may eliminate the need
to wrap it in subclasses, but I'm not going to test that.
Wrap `__rmul__` for BoundedField to eliminate the need to wrap
it in subclasses.

Update the `ChebyshevBoundedField` pybind11 wrapper accordingly:
remove the wrapper for `__ne__` and `__rmul__`.
@r-owen r-owen merged commit 2e6042a into master Jul 10, 2017
@ktlim ktlim deleted the tickets/DM-10777 branch August 25, 2018 06: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
Development

Successfully merging this pull request may close these issues.

None yet

4 participants