File: | src/sky/GWcsMER.cpp |
Location: | line 464, column 13 |
Description: | Value stored to 'status' is never read |
1 | /*************************************************************************** |
2 | * GWcsMER.cpp - Mercator's (MER) projection class * |
3 | * ----------------------------------------------------------------------- * |
4 | * copyright (C) 2012-2013 by Juergen Knoedlseder * |
5 | * ----------------------------------------------------------------------- * |
6 | * * |
7 | * This program is free software: you can redistribute it and/or modify * |
8 | * it under the terms of the GNU General Public License as published by * |
9 | * the Free Software Foundation, either version 3 of the License, or * |
10 | * (at your option) any later version. * |
11 | * * |
12 | * This program is distributed in the hope that it will be useful, * |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
15 | * GNU General Public License for more details. * |
16 | * * |
17 | * You should have received a copy of the GNU General Public License * |
18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. * |
19 | * * |
20 | ***************************************************************************/ |
21 | /** |
22 | * @file GWcsMER.cpp |
23 | * @brief Mercator's (MER) projection class implementation |
24 | * @author Juergen Knoedlseder |
25 | */ |
26 | |
27 | /* __ Includes ___________________________________________________________ */ |
28 | #ifdef HAVE_CONFIG_H1 |
29 | #include <config.h> |
30 | #endif |
31 | #include "GException.hpp" |
32 | #include "GMath.hpp" |
33 | #include "GWcsMER.hpp" |
34 | #include "GWcsRegistry.hpp" |
35 | |
36 | /* __ Method name definitions ____________________________________________ */ |
37 | |
38 | /* __ Macros _____________________________________________________________ */ |
39 | |
40 | /* __ Coding definitions _________________________________________________ */ |
41 | |
42 | /* __ Debug definitions __________________________________________________ */ |
43 | |
44 | /* __ Local prototypes ___________________________________________________ */ |
45 | |
46 | /* __ Constants __________________________________________________________ */ |
47 | |
48 | /* __ Globals ____________________________________________________________ */ |
49 | const GWcsMER g_wcs_mer_seed; |
50 | const GWcsRegistry g_wcs_mer_registry(&g_wcs_mer_seed); |
51 | |
52 | |
53 | /*========================================================================== |
54 | = = |
55 | = Constructors/destructors = |
56 | = = |
57 | ==========================================================================*/ |
58 | |
59 | /***********************************************************************//** |
60 | * @brief Void constructor |
61 | ***************************************************************************/ |
62 | GWcsMER::GWcsMER(void) : GWcs() |
63 | { |
64 | // Initialise class members |
65 | init_members(); |
66 | |
67 | // Return |
68 | return; |
69 | } |
70 | |
71 | |
72 | /***********************************************************************//** |
73 | * @brief Projection constructor |
74 | * |
75 | * @param[in] coords Coordinate system. |
76 | * @param[in] crval1 X value of reference pixel. |
77 | * @param[in] crval2 Y value of reference pixel. |
78 | * @param[in] crpix1 X index of reference pixel (starting from 1). |
79 | * @param[in] crpix2 Y index of reference pixel (starting from 1). |
80 | * @param[in] cdelt1 Increment in x direction at reference pixel [deg]. |
81 | * @param[in] cdelt2 Increment in y direction at reference pixel [deg]. |
82 | ***************************************************************************/ |
83 | GWcsMER::GWcsMER(const std::string& coords, |
84 | const double& crval1, const double& crval2, |
85 | const double& crpix1, const double& crpix2, |
86 | const double& cdelt1, const double& cdelt2) : |
87 | GWcs(coords, crval1, crval2, crpix1, crpix2, cdelt1, cdelt2) |
88 | |
89 | { |
90 | // Initialise class members |
91 | init_members(); |
92 | |
93 | // Return |
94 | return; |
95 | } |
96 | |
97 | |
98 | /***********************************************************************//** |
99 | * @brief Copy constructor |
100 | * |
101 | * @param[in] wcs World Coordinate System. |
102 | ***************************************************************************/ |
103 | GWcsMER::GWcsMER(const GWcsMER& wcs) : GWcs(wcs) |
104 | { |
105 | // Initialise class members for clean destruction |
106 | init_members(); |
107 | |
108 | // Copy members |
109 | copy_members(wcs); |
110 | |
111 | // Return |
112 | return; |
113 | } |
114 | |
115 | |
116 | /***********************************************************************//** |
117 | * @brief Destructor |
118 | ***************************************************************************/ |
119 | GWcsMER::~GWcsMER(void) |
120 | { |
121 | // Free members |
122 | free_members(); |
123 | |
124 | // Return |
125 | return; |
126 | } |
127 | |
128 | |
129 | /*========================================================================== |
130 | = = |
131 | = Operators = |
132 | = = |
133 | ==========================================================================*/ |
134 | |
135 | /***********************************************************************//** |
136 | * @brief Assignment operator |
137 | * |
138 | * @param[in] wcs World Coordinate System. |
139 | * @return World Coordinate System. |
140 | ***************************************************************************/ |
141 | GWcsMER& GWcsMER::operator=(const GWcsMER& wcs) |
142 | { |
143 | // Execute only if object is not identical |
144 | if (this != &wcs) { |
145 | |
146 | // Copy base class members |
147 | this->GWcs::operator=(wcs); |
148 | |
149 | // Free members |
150 | free_members(); |
151 | |
152 | // Initialise private members for clean destruction |
153 | init_members(); |
154 | |
155 | // Copy members |
156 | copy_members(wcs); |
157 | |
158 | } // endif: object was not identical |
159 | |
160 | // Return this object |
161 | return *this; |
162 | } |
163 | |
164 | |
165 | /*========================================================================== |
166 | = = |
167 | = Public methods = |
168 | = = |
169 | ==========================================================================*/ |
170 | |
171 | /***********************************************************************//** |
172 | * @brief Clear Mercator's projection |
173 | * |
174 | * This method properly resets the object to an initial state. |
175 | ***************************************************************************/ |
176 | void GWcsMER::clear(void) |
177 | { |
178 | // Free class members (base and derived classes, derived class first) |
179 | free_members(); |
180 | this->GWcs::free_members(); |
181 | this->GSkyProjection::free_members(); |
182 | |
183 | // Initialise members |
184 | this->GSkyProjection::init_members(); |
185 | this->GWcs::init_members(); |
186 | init_members(); |
187 | |
188 | // Return |
189 | return; |
190 | } |
191 | |
192 | |
193 | /***********************************************************************//** |
194 | * @brief Clone Mercator's projection |
195 | * |
196 | * @return Pointer to deep copy of Mercator's projection. |
197 | ***************************************************************************/ |
198 | GWcsMER* GWcsMER::clone(void) const |
199 | { |
200 | return new GWcsMER(*this); |
201 | } |
202 | |
203 | |
204 | /***********************************************************************//** |
205 | * @brief Print WCS information |
206 | * |
207 | * @param[in] chatter Chattiness (defaults to NORMAL). |
208 | * @return String containing Mercator's projection information. |
209 | ***************************************************************************/ |
210 | std::string GWcsMER::print(const GChatter& chatter) const |
211 | { |
212 | // Initialise result string |
213 | std::string result; |
214 | |
215 | // Continue only if chatter is not silent |
216 | if (chatter != SILENT) { |
217 | |
218 | // Append header |
219 | result.append("=== GWcsMER ==="); |
220 | |
221 | // Append information |
222 | result.append(wcs_print(chatter)); |
223 | |
224 | } // endif: chatter was not silent |
225 | |
226 | // Return result |
227 | return result; |
228 | } |
229 | |
230 | |
231 | /*========================================================================== |
232 | = = |
233 | = Private methods = |
234 | = = |
235 | ==========================================================================*/ |
236 | |
237 | /***********************************************************************//** |
238 | * @brief Initialise class members |
239 | * |
240 | * This method sets up the World Coordinate System by calling wcs_set(). |
241 | ***************************************************************************/ |
242 | void GWcsMER::init_members(void) |
243 | { |
244 | // Setup World Coordinate System |
245 | wcs_set(); |
246 | |
247 | // Return |
248 | return; |
249 | } |
250 | |
251 | |
252 | /***********************************************************************//** |
253 | * @brief Copy class members |
254 | * |
255 | * @param[in] wcs World Coordinate System. |
256 | ***************************************************************************/ |
257 | void GWcsMER::copy_members(const GWcsMER& wcs) |
258 | { |
259 | // Return |
260 | return; |
261 | } |
262 | |
263 | |
264 | /***********************************************************************//** |
265 | * @brief Delete class members |
266 | ***************************************************************************/ |
267 | void GWcsMER::free_members(void) |
268 | { |
269 | // Return |
270 | return; |
271 | } |
272 | |
273 | |
274 | /***********************************************************************//** |
275 | * @brief Setup of projection |
276 | * |
277 | * This method sets up the projection information. The method has been |
278 | * adapted from the wcslib function prj.c::merset. |
279 | * |
280 | * Given and/or returned: |
281 | * m_r0 Reset to 180/pi if 0. |
282 | * m_phi0 Reset to 0.0 if undefined. |
283 | * m_theta0 Reset to 0.0 if undefined. |
284 | * |
285 | * Returned: |
286 | * m_x0 Fiducial offset in x. |
287 | * m_y0 Fiducial offset in y. |
288 | * m_w[0] r0*(pi/180) |
289 | * m_w[1] (180/pi)/r0 |
290 | ***************************************************************************/ |
291 | void GWcsMER::prj_set(void) const |
292 | { |
293 | // Initialise projection parameters |
294 | m_w.clear(); |
295 | |
296 | // Precompute |
297 | if (m_r0 == 0.0) { |
298 | m_r0 = gammalib::rad2deg; |
299 | m_w.push_back(1.0); |
300 | m_w.push_back(1.0); |
301 | } |
302 | else { |
303 | m_w.push_back(m_r0 * gammalib::deg2rad); |
304 | m_w.push_back(1.0/m_w[0]); |
305 | } |
306 | |
307 | // Compute fiducial offset |
308 | prj_off(0.0, 0.0); |
309 | |
310 | // Signal that projection has been set |
311 | m_prjset = true; |
312 | |
313 | // Return |
314 | return; |
315 | } |
316 | |
317 | |
318 | /***********************************************************************//** |
319 | * @brief Pixel-to-spherical deprojection |
320 | * |
321 | * @param[in] nx X vector length. |
322 | * @param[in] ny Y vector length (0=no replication). |
323 | * @param[in] sxy Input vector step. |
324 | * @param[in] spt Output vector step. |
325 | * @param[in] x Vector of projected x coordinates. |
326 | * @param[in] y Vector of projected y coordinates. |
327 | * @param[out] phi Longitude of the projected point in native spherical |
328 | * coordinates [deg]. |
329 | * @param[out] theta Latitude of the projected point in native spherical |
330 | * coordinates [deg]. |
331 | * @param[out] stat Status return value for each vector element (always 0) |
332 | * |
333 | * Deproject pixel (x,y) coordinates in the plane of projection to native |
334 | * spherical coordinates (phi,theta). |
335 | * |
336 | * This method has been adapted from the wcslib function prj.c::merx2s(). |
337 | * The interface follows very closely that of wcslib. In contrast to the |
338 | * wcslib routine, however, the method assumes that the projection has been |
339 | * setup previously (as this will be done by the constructor). |
340 | ***************************************************************************/ |
341 | void GWcsMER::prj_x2s(int nx, int ny, int sxy, int spt, |
342 | const double* x, const double* y, |
343 | double* phi, double* theta, int* stat) const |
344 | { |
345 | // Initialize projection if required |
346 | if (!m_prjset) { |
347 | prj_set(); |
348 | } |
349 | |
350 | // Set value replication length mx,my |
351 | int mx; |
352 | int my; |
353 | if (ny > 0) { |
354 | mx = nx; |
355 | my = ny; |
356 | } |
357 | else { |
358 | mx = 1; |
359 | my = 1; |
360 | ny = nx; |
361 | } |
362 | |
363 | // Do x dependence |
364 | const double* xp = x; |
365 | int rowoff = 0; |
366 | int rowlen = nx * spt; |
367 | for (int ix = 0; ix < nx; ++ix, rowoff += spt, xp += sxy) { |
368 | double s = m_w[1] * (*xp + m_x0); |
369 | double* phip = phi + rowoff; |
370 | for (int iy = 0; iy < my; ++iy, phip += rowlen) { |
371 | *phip = s; |
372 | } |
373 | } |
374 | |
375 | // Do y dependence |
376 | const double* yp = y; |
377 | double* thetap = theta; |
378 | int* statp = stat; |
379 | for (int iy = 0; iy < ny; ++iy, yp += sxy) { |
380 | double t = 2.0 * gammalib::atand(std::exp((*yp + m_y0)/m_r0)) - 90.0; |
381 | for (int ix = 0; ix < mx; ++ix, thetap += spt) { |
382 | *thetap = t; |
383 | *(statp++) = 0; |
384 | } |
385 | } |
386 | |
387 | // Return |
388 | return; |
389 | } |
390 | |
391 | |
392 | /***********************************************************************//** |
393 | * @brief Generic spherical-to-pixel projection |
394 | * |
395 | * @param[in] nphi Longitude vector length. |
396 | * @param[in] ntheta Latitude vector length (0=no replication). |
397 | * @param[in] spt Input vector step. |
398 | * @param[in] sxy Output vector step. |
399 | * @param[in] phi Longitude vector of the projected point in native spherical |
400 | * coordinates [deg]. |
401 | * @param[in] theta Latitude vector of the projected point in native spherical |
402 | * coordinates [deg]. |
403 | * @param[out] x Vector of projected x coordinates. |
404 | * @param[out] y Vector of projected y coordinates. |
405 | * @param[out] stat Status return value for each vector element (always 0) |
406 | * |
407 | * Project native spherical coordinates (phi,theta) to pixel (x,y) |
408 | * coordinates in the plane of projection. |
409 | * |
410 | * This method has been adapted from the wcslib function prj.c::mers2x(). |
411 | * The interface follows very closely that of wcslib. In contrast to the |
412 | * wcslib routine, however, the method assumes that the projection has been |
413 | * setup previously (as this will be done by the constructor). |
414 | ***************************************************************************/ |
415 | void GWcsMER::prj_s2x(int nphi, int ntheta, int spt, int sxy, |
416 | const double* phi, const double* theta, |
417 | double* x, double* y, int* stat) const |
418 | { |
419 | // Initialize projection if required |
420 | if (!m_prjset) { |
421 | prj_set(); |
422 | } |
423 | |
424 | // Set value replication length mphi,mtheta |
425 | int mphi; |
426 | int mtheta; |
427 | if (ntheta > 0) { |
428 | mphi = nphi; |
429 | mtheta = ntheta; |
430 | } |
431 | else { |
432 | mphi = 1; |
433 | mtheta = 1; |
434 | ntheta = nphi; |
435 | } |
436 | |
437 | // Initialise status code and statistics |
438 | int status = 0; |
439 | int n_invalid = 0; |
440 | |
441 | // Do phi dependence |
442 | const double* phip = phi; |
443 | int rowoff = 0; |
444 | int rowlen = nphi * sxy; |
445 | for (int iphi = 0; iphi < nphi; ++iphi, rowoff += sxy, phip += spt) { |
446 | double xi = m_w[0] * (*phip) - m_x0; |
447 | double* xp = x + rowoff; |
448 | for (int itheta = 0; itheta < mtheta; ++itheta, xp += rowlen) { |
449 | *xp = xi; |
450 | } |
451 | } |
452 | |
453 | |
454 | // Do theta dependence |
455 | const double* thetap = theta; |
456 | double* yp = y; |
457 | int* statp = stat; |
458 | for (int itheta = 0; itheta < ntheta; ++itheta, thetap += spt) { |
459 | double eta; |
460 | int istat = 0; |
461 | if (*thetap <= -90.0 || *thetap >= 90.0) { |
462 | eta = 0.0; |
463 | istat = 1; |
464 | status = 3; |
Value stored to 'status' is never read | |
465 | n_invalid++; |
466 | } else { |
467 | eta = m_r0 * std::log(gammalib::tand((*thetap+90.0)/2.0)) - m_y0; |
468 | } |
469 | for (int iphi = 0; iphi < mphi; ++iphi, yp += sxy) { |
470 | *yp = eta; |
471 | *(statp++) = istat; |
472 | } |
473 | } |
474 | |
475 | // Return |
476 | return; |
477 | } |