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-10728: miscellaneous changes in support of PhotoCalib outputs in meas_mosaic #253

Merged
merged 7 commits into from Jul 28, 2017

Conversation

TallJimbo
Copy link
Member

No description provided.

@parejkoj
Copy link
Contributor

parejkoj commented Jul 4, 2017

My first concern is your change of _instFlux[Err] -> _flux[Sigma]; I tried very hard to get PhotoCalib self-consistent in its use of instFlux and Err.

Talking with @SimonKrughoff about this just now, the question is whether you can hold off a month or two for us to make the big instFlux and Sigma->Err changes, or whether we make this change (making PhotoCalib no longer self-consistent), and revert it later? Thoughts?

Copy link
Contributor

@parejkoj parejkoj left a comment

Choose a reason for hiding this comment

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

Handful of comments, but the big question was my previous comment re: instFlux.

clsChebyshevBoundedField.def("__eq__", &BoundedField::operator==, py::is_operator());
clsChebyshevBoundedField.def("__ne__", &BoundedField::operator!=, py::is_operator());
/* Operators are defined only in the BoundedField base class;
we let Python inheritance provide them here. */
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice improvement.

@@ -285,7 +284,7 @@ std::pair<ndarray::Array<double, 1>, ndarray::Array<double, 1>> Calib::getMagnit
continue;
}
double f, df;
convertToMagWithErr(&f, &df, _fluxMag0, fluxMag0InvSNR, *fluxIter, *fluxErrIter);
Copy link
Contributor

Choose a reason for hiding this comment

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

Wow, it was even more internally-inconsistent than I'd previously thought?

y0 = y1;
y1 += yStep;
}
{
Copy link
Contributor

Choose a reason for hiding this comment

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

What's this second bracket-block for?

z00 = z10;
z01 = z11;
}
{
Copy link
Contributor

Choose a reason for hiding this comment

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

What's this second bracket-block for?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's conceptually a special-cased last iteration of the loop, and I like to do that at the same/scope indentation level as the rest of the loop body. I'll add a comment to that effect.

// Local function to do bilinear interpolation using points
// [(x0, y0), (x0, y1), (x1, y0), (x1, y1)] with values
// [z00, z01, z10, z11], in pixels [x0:xEnd, y0:yEnd]
auto interpolate = [&img, &functor](
Copy link
Contributor

Choose a reason for hiding this comment

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

I feel like interpolate and processRowBlock are complicated enough that they should be anonymous functions instead of lambdas. I'd strongly make that case in python (or that they at least be inner functions), but I don't know what the standard is in C++, and our dev guide doesn't even mention lambdas.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm still learning when use C++ lambdas myself, but I like the way this encapsulates the local functions inside the only scope where they're used. Would be interested in @pschella's and @kfindeisen's opinions on best-practices here.

Copy link
Member

Choose a reason for hiding this comment

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

Hmm... dejà vu.

I agree with @parejkoj that these lambdas are way too long and that they should be proper functions (C++ doesn't have anonymous functions, BTW). Having this code in the middle of applyToImage just makes it hard to read (I already mistook the end of interpolate for the end of applyToImage, for example). Lambdas are designed for the strategy pattern and, to a lesser degree, functional programming, and neither seems to be happening here.

Copy link
Member

@kfindeisen kfindeisen Jul 5, 2017

Choose a reason for hiding this comment

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

Also, this is a very long parameter list with identical/compatible types. Is there some way to factor it (XYZ triplets, BoundingBoxes, etc.)?

Copy link
Member Author

Choose a reason for hiding this comment

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

I've refactored the interpolation code along both of these lines (no more lambdas, factored parameter lists). Please feel welcome (but not compelled) to take another look.

field.fillImage(image2, xStep=3)
field.fillImage(image3, yStep=4)
field.fillImage(image4, xStep=3, yStep=4)
self.assertFloatsAlmostEqual(image1.array, image2.array, rtol=2E-2, atol=2E-2)
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't the tolerances for these each be different, since the step sizes are different?

@TallJimbo
Copy link
Member Author

The change from instFlux->flux (etc) is a single commit that can and should be reverted easily later. Until the SourceCatalogs we produce adopt the new conventions, I think it's much more valuable to have usable code than self-consistent naming.

And as much as I'm in favor of switching to the new conventions, I'm worried that backwards compatibility requirements may drag that conversion out longer than we'd all like.

@TallJimbo TallJimbo force-pushed the tickets/DM-10728 branch 2 times, most recently from c718b8f to 8169830 Compare July 28, 2017 15:47
This can drastically reduce the evaluation time for large images, as it
avoids a virtual function call at every pixel and allows a lot more
compiler optimization.  An interface for vectorized evaluation of
BoundedField would also be good, but it's a much harder design problem.
Inheriting from PersistableFacade in subclasses isn't necessary,
because pybind11 automatically downcasts C++ pointers when
converting to Python, and downcasting is all PersistableFacade does.

Removing that inheritance lets derived BoundedFields inherit
operators (especially equality operators), which would otherwise go
to the implementation PersistableFacade inherits from object.

See DM-10899 for more information.
This may need to be reverted as part of the implementations of RFCs 333
and 356, but until then we should prefer working code to future-proof
code.
Old code overestimated the contribution from fluxMag0Err by dividing it
by the source flux instead of fluxMag0.
@TallJimbo TallJimbo merged commit 036366c into master Jul 28, 2017
@ktlim ktlim deleted the tickets/DM-10728 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

3 participants