CR2RE Pipeline Reference Manual 1.6.7
hdrl_cat_phopt.c
1/*
2 * This file is part of the HDRL
3 * Copyright (C) 2017 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include "hdrl_cat_phopt.h"
21
22#include "hdrl_cat_utils.h"
23
24
25/*---------------------------------------------------------------------------*/
33/*----------------------------------------------------------------------------*/
34
37/* ---------------------------------------------------------------------------*/
58/* ---------------------------------------------------------------------------*/
59cpl_error_code hdrl_phopt(
60 ap_t *ap, double parm[IMNUM][NPAR], cpl_size nbit, cpl_size naper,
61 double apertures[], double cflux[], double badpix[], cpl_size nrcore, double avconf[])
62{
63 /* Set up some local variables */
64 double *map = ap->indata;
65 double *conf = ap->confdata;
66 unsigned char *mflag = ap->mflag;
67 cpl_size nx = ap->lsiz;
68 cpl_size ny = ap->csiz;
69
70 /* Loop for each of the apertures */
71 double aa[IMNUM+1][IMNUM+1];
72 double bb[IMNUM+1];
73
74 for (cpl_size iaper = 0; iaper < naper; iaper++) {
75
76 double rcirc = apertures[iaper];
77 double parrad = rcirc + 0.5;
78
79 /* profile normalising constant */
80 double cn = 1. / (CPL_MATH_PI * rcirc * rcirc);
81 double cnsq = cn * cn;
82
83 /* set up covariance matrix - analytic special case for cores */
84 for (cpl_size i = 0; i < nbit; i++) {
85
86 /* overlaps totally area=pi*r**2 */
87 aa[i][i] = cn;
88
89 if (nbit > 1) {
90
91 double xi = parm[i][1];
92 double yi = parm[i][2];
93
94 for (cpl_size j = i + 1; j < nbit; j++) {
95
96 double d = sqrt( (xi - parm[j][1]) * (xi - parm[j][1])
97 + (yi - parm[j][2]) * (yi - parm[j][2]));
98
99 if (d >= 2. * rcirc) {
100 aa[j][i] = 0.;
101 } else {
102 double arg = d / (2. * rcirc);
103 aa[j][i] = cnsq * 2. * rcirc * rcirc * (acos(arg)
104 - arg * (sqrt(1. - arg * arg)));
105 }
106
107 aa[i][j] = aa[j][i];
108 }
109 }
110 }
111
112 /* clear accumulators */
113 for (cpl_size i = 0; i < nbit; i++) {
114 bb[i] = 0.;
115 }
116
117 /* generate image-blend outer boundaries */
118 double xmin = DBL_MAX;
119 double xmax = DBL_MIN;
120 double ymin = DBL_MAX;
121 double ymax = DBL_MIN;
122
123 for (cpl_size i = 0; i < nbit; i++) {
124
125 double xi = parm[i][1];
126 double yi = parm[i][2];
127
128 xmin = CPL_MIN(xmin, xi);
129 xmax = CPL_MAX(xmax, xi);
130 ymin = CPL_MIN(ymin, yi);
131 ymax = CPL_MAX(ymax, yi);
132 }
133
134 double ix1 = CPL_MAX( 0, (cpl_size)(xmin - parrad) - 1);
135 double ix2 = CPL_MIN(nx - 1, (cpl_size)(xmax + parrad) );
136
137 double iy1 = CPL_MAX( 0, (cpl_size)(ymin - parrad) - 1);
138 double iy2 = CPL_MIN(ny - 1, (cpl_size)(ymax + parrad) );
139
140 /* now go through pixel region */
141 for (cpl_size ii = iy1; ii <= iy2; ii++) {
142
143 cpl_size kk = ii * nx;
144
145 for (cpl_size i = ix1; i <= ix2; i++) {
146
147 unsigned char mf = mflag[kk+i];
148
149 if (mf == MF_ZEROCONF || mf == MF_STUPID_VALUE) {
150
151 for (cpl_size j = 0; j < nbit; j++) {
152
153 double xj = i - parm[j][1] + 1.;
154 double yj = ii - parm[j][2] + 1.;
155 double tj = fraction(xj, yj, rcirc);
156
157 aa[j][j] -= tj * tj * cnsq;
158
159 for (cpl_size k = j + 1; k < nbit; k++) {
160 double tk = fraction( i - parm[k][1] + 1., ii - parm[k][2] + 1., rcirc);
161 aa[k][j] -= tk * tj * cnsq;
162 aa[j][k] = aa[k][j];
163 }
164
165 if (iaper == nrcore) badpix[j] += tj;
166 }
167
168 } else if (mf == MF_CLEANPIX || mf == MF_OBJPIX || mf == MF_SATURATED) {
169
170 double t = map[kk+i];
171
172 for (cpl_size j = 0; j < nbit; j++) {
173
174 double xj = i - parm[j][1] + 1.;
175 double yj = ii - parm[j][2] + 1.;
176
177 double ff = fraction(xj, yj, rcirc);
178
179 bb[j] += ff * t;
180
181 if (iaper == nrcore) {
182 avconf[j] += ff * conf[kk + i];
183 }
184 }
185 }
186 }
187 }
188
189 if (nbit == 1) {
190
191 /* Trivial solution for single object */
192 cflux[iaper] = bb[0];
193
194 } else {
195
196 /* solve for profile intensities */
197 for (cpl_size i = 0; i < nbit; i++) {
198 aa[i][i] = CPL_MAX(aa[i][i], cnsq);
199 }
200
201 /* Could be better to call --> cpl_matrix_decomp_chol(...); */
202 dchole(aa, bb, nbit);
203
204 for (cpl_size i = 0; i < nbit; i++) {
205 cflux[i * naper + iaper] = cn * bb[i];
206 }
207 }
208 }
209
210 return CPL_ERROR_NONE;
211}
212
cpl_error_code hdrl_phopt(ap_t *ap, double parm[IMNUM][NPAR], cpl_size nbit, cpl_size naper, double apertures[], double cflux[], double badpix[], cpl_size nrcore, double avconf[])
Does multiple profile fitting to determine intensities.
double fraction(double x, double y, double r_out)
Fraction of pixel bounded.
void dchole(double a[IMNUM+1][IMNUM+1], double b[IMNUM+1], cpl_size n)
Cholesky decomposition of definite symmetric matrix to solve Ax = b.