201 auto coord = frame_coordinates->worldToImage(
207 double x_basis_x = std::get<0>(jacobian);
208 double x_basis_y = std::get<1>(jacobian);
209 double y_basis_x = std::get<2>(jacobian);
210 double y_basis_y = std::get<3>(jacobian);
213 double major_x = ellipse.
m_a * cos_theta;
214 double major_y = ellipse.
m_a * sin_theta;
215 double minor_x = -ellipse.
m_b * sin_theta;
216 double minor_y = ellipse.
m_b * cos_theta;
219 double new_major_x = major_x * x_basis_x + major_y * y_basis_x;
220 double new_major_y = major_x * x_basis_y + major_y * y_basis_y;
223 double new_minor_x = minor_x * x_basis_x + minor_y * y_basis_x;
224 double new_minor_y = minor_x * x_basis_y + minor_y * y_basis_y;
227 double new_a =
std::sqrt(new_major_x * new_major_x + new_major_y * new_major_y);
228 double new_b =
std::sqrt(new_minor_x * new_minor_x + new_minor_y * new_minor_y);
231 double new_theta =
std::atan2(new_major_y, new_major_x);
233 return {coord.m_x, coord.m_y, new_a, new_b, new_theta};
258 int frame_index = frame->getFrameNb();
270 auto source_psf =
DownSampledImagePsf(psf_property.getPixelSampling(), psf_property.getPsf(),
278 for (
auto model : frame->getModels()) {
279 model->addForSource(manager, source, constant_models, point_models, extended_models, model_size,
280 jacobian, ref_coordinates, frame_coordinates, stamp_rect.
getTopLeft());
302 SeFloat gain = frame_info.getGain();
303 SeFloat saturation = frame_info.getSaturation();
312 auto rad =
std::min(unclipped_rect.getWidth() / 2.0, unclipped_rect.getHeight() / 2.0) - 1.0;
319 auto coord = frame_coordinates->worldToImage(centroid.getCentroid());
320 ellipse.
m_x = coord.m_x;
321 ellipse.
m_y = coord.m_y;
334 double A = (cos_theta * cos_theta) / a_squared + (sin_theta * sin_theta) / b_squared;
335 double B = 2 * cos_theta * sin_theta * (1 / a_squared - 1 / b_squared);
336 double C = (sin_theta * sin_theta) / a_squared + (cos_theta * cos_theta) / b_squared;
338 for (
int y = 0; y < rect.getHeight(); y++) {
339 for (
int x = 0; x < rect.getWidth(); x++) {
340 auto back_var = variance_map->getValue(rect.getTopLeft().m_x + x, rect.getTopLeft().m_y + y);
341 auto pixel_val = frame_image->getValue(rect.getTopLeft().m_x + x, rect.getTopLeft().m_y + y);
343 auto dx = x + rect.getTopLeft().m_x - ellipse.
m_x;
344 auto dy = y + rect.getTopLeft().m_y - ellipse.
m_y;
346 if (saturation > 0 && pixel_val > saturation) {
347 weight->at(x, y) = 0;
348 }
else if (gain > 0.0 && pixel_val > 0.0) {
349 weight->at(x, y) =
sqrt(1.0 / (back_var + pixel_val / gain));
351 weight->at(x, y) =
sqrt(1.0 / back_var);
356 if (dx * dx + dy * dy > rad * rad) {
357 weight->at(x, y) = 0;
360 auto w = unclipped_rect.getWidth() / 2.0;
361 auto h = unclipped_rect.getHeight() / 2.0;
362 if (dx / w * dx / w + dy / h * dy / h > 1) {
363 weight->at(x, y) = 0;
367 double value = A * dx * dx + B * dx * dy + C * dy * dy;
369 weight->at(x, y) = 0;
381 for (
auto& source : group) {
391 if (free_parameter !=
nullptr) {
393 initial_state.
parameters_values[free_parameter->getId()] = free_parameter->getInitialValue(source);
404 int frame_index = frame->getFrameNb();
423 double prev_chi_squared = 999999.9;
426 for (
auto& source : group) {
427 fitSource(group, source, index, fitting_state);
433 double chi_squared = 0.0;
435 chi_squared += source_state.reduced_chi_squared;
443 prev_chi_squared = chi_squared;
449 for (
size_t index = 0; index < group.
size(); index++){
455 if (free_parameter !=
nullptr && !source_state.parameters_fitted[parameter->getId()]) {
464 for (
auto& source : group) {
467 int meta_iterations = source_state.chi_squared_per_meta.size();
472 source_state.reduced_chi_squared, source_state.duration, source_state.flags,
473 source_state.parameters_values, source_state.parameters_sigmas,
474 source_state.chi_squared_per_meta, source_state.iterations_per_meta,
475 meta_iterations, source_state.fitting_areas_x, source_state.fitting_areas_y);
487 int frame_index = frame->getFrameNb();
493 int n_free_parameters = 0;
496 for (
auto& src : group) {
497 if (index != source_index) {
501 if (free_parameter !=
nullptr) {
506 free_parameter->create(parameter_manager, engine_parameter_manager, src,
507 state.
source_states[index].parameters_initial_values.at(free_parameter->getId()),
508 state.
source_states[index].parameters_values.at(free_parameter->getId())));
511 parameter->create(parameter_manager, engine_parameter_manager, src));
520 for (
auto& src : group) {
521 if (index != source_index) {
523 auto final_stamp = frame_model.getImage();
525 for (
int y = 0; y < final_stamp->getHeight(); ++y) {
526 for (
int x = 0; x < final_stamp->getWidth(); ++x) {
527 deblend_image->at(x, y) += final_stamp->at(x, y);
534 return deblend_image;
541 int free_parameters_nb = 0;
545 if (free_parameter !=
nullptr) {
546 ++free_parameters_nb;
550 free_parameter->create(parameter_manager, engine_parameter_manager, source,
551 state.
source_states[index].parameters_initial_values.at(free_parameter->getId()),
552 state.
source_states[index].parameters_values.at(free_parameter->getId())));
555 parameter->create(parameter_manager, engine_parameter_manager, source));
563 return free_parameters_nb;
572 int valid_frames = 0;
574 int frame_index = frame->getFrameNb();
585 for (
int y = 0; y < image->getHeight(); ++y) {
586 for (
int x = 0; x < image->getWidth(); ++x) {
594 for (
int y = 0; y < weight->getHeight(); ++y) {
595 for (
int x = 0; x < weight->getWidth(); ++x) {
596 good_pixels += (weight->at(x, y) != 0.);
635 SeFloat avg_reduced_chi_squared,
SeFloat duration,
unsigned int iterations,
unsigned int stop_reason,
Flags flags,
646 bool accessed_by_modelfitting = parameter_manager.
isParamAccessed(source, parameter);
647 auto modelfitting_parameter = parameter_manager.
getParameter(source, parameter);
649 if (is_constant_parameter || is_dependent_parameter || accessed_by_modelfitting) {
650 parameters_values[parameter->getId()] = modelfitting_parameter->getValue();
651 parameters_sigmas[parameter->getId()] = parameter->getSigma(parameter_manager, source, solution.
parameter_sigmas);
652 parameters_fitted[parameter->getId()] =
true;
654 parameters_values[parameter->getId()] = state.
source_states[index].parameters_values[parameter->getId()];
655 parameters_sigmas[parameter->getId()] = state.
source_states[index].parameters_sigmas[parameter->getId()];
656 parameters_fitted[parameter->getId()] =
false;
660 if (engine_parameter) {
668 state.
source_states[index].parameters_values = parameters_values;
669 state.
source_states[index].parameters_sigmas = parameters_sigmas;
670 state.
source_states[index].parameters_fitted = parameters_fitted;
671 state.
source_states[index].reduced_chi_squared = avg_reduced_chi_squared;
672 state.
source_states[index].chi_squared_per_meta.emplace_back(avg_reduced_chi_squared);
675 state.
source_states[index].iterations_per_meta.emplace_back(iterations);
687 int frame_index = frame->getFrameNb();
692 fit_size =
std::max(fit_size, stamp_rect.getWidth() * stamp_rect.getHeight() /
693 (psf_property.getPixelSampling() * psf_property.getPixelSampling()));
701 <<
" scaling factor: " << down_scaling;
710 parameter_manager, engine_parameter_manager, source, index, state);
715 int n_good_pixels = 0;
717 parameter_manager, res_estimator, n_good_pixels, group, source, index, state, down_scaling);
724 if (valid_frames == 0) {
727 else if (n_good_pixels < n_free_parameters) {
736 if (down_scaling < 1.0) {
744 prior->setupPrior(parameter_manager, source, res_estimator);
751 auto solution = engine->solveProblem(engine_parameter_manager, res_estimator);
753 auto iterations = solution.iteration_no;
754 auto stop_reason = solution.engine_stop_reason;
758 auto duration = solution.duration;
767 fitSourceUpdateState(parameter_manager, source, avg_reduced_chi_squared, duration, iterations, stop_reason, flags, solution,
780 for (
auto& src : group) {
784 if (free_parameter !=
nullptr) {
787 free_parameter->create(parameter_manager, engine_parameter_manager, src,
788 state.
source_states[index].parameters_initial_values.at(free_parameter->getId()),
789 state.
source_states[index].parameters_values.at(free_parameter->getId())));
792 parameter->create(parameter_manager, engine_parameter_manager, src));
798 for (
auto& src : group) {
800 int frame_index = frame->getFrameNb();
806 auto final_stamp = frame_model.getImage();
814 for (
int x = 0; x < final_stamp->getWidth(); x++) {
815 for (
int y = 0; y < final_stamp->getHeight(); y++) {
816 auto x_coord = stamp_rect.getTopLeft().m_x + x;
817 auto y_coord = stamp_rect.getTopLeft().m_y + y;
818 debug_image->setValue(x_coord, y_coord,
819 debug_accessor.
getValue(x_coord, y_coord) + final_stamp->getValue(x, y));
829 for (
int x = 0; x < final_stamp->getWidth(); x++) {
830 for (
int y = 0; y < final_stamp->getHeight(); y++) {
831 auto x_coord = stamp_rect.getTopLeft().m_x + x;
832 auto y_coord = stamp_rect.getTopLeft().m_y + y;
833 if (weight_image->getValue(x, y) > 0.0) {
834 window_image->setValue(x_coord, y_coord, window_accessor.
getValue(x_coord, y_coord) + 2);
836 window_image->setValue(x_coord, y_coord, window_accessor.
getValue(x_coord, y_coord) + 1);
871 total_data_points = 0;
872 int valid_frames = 0;
874 int frame_index = frame->getFrameNb();
880 auto final_stamp = frame_model.getImage();
884 for (
int y = 0; y < image->getHeight(); ++y) {
885 for (
int x = 0; x < image->getWidth(); ++x) {
886 image->at(x, y) -= deblend_image->at(x, y);
895 total_data_points += data_points;
896 total_chi_squared += chi_squared;
900 return total_chi_squared;
std::unique_ptr< DataVsModelResiduals< typename std::remove_reference< DataType >::type, typename std::remove_reference< ModelType >::type, typename std::remove_reference< WeightType >::type, typename std::remove_reference< Comparator >::type > > createDataVsModelResiduals(DataType &&data, ModelType &&model, WeightType &&weight, Comparator &&comparator)